refactor: migrate to angular esbuild

refactor: migrate to ionic standalone components
refactor: migrate ion icons to a custom element
This commit is contained in:
2024-07-02 17:28:57 +02:00
committed by Rainer Killinger
parent 436e1471a7
commit b8ac30b9d0
118 changed files with 1060 additions and 844 deletions

View File

@@ -4,10 +4,10 @@
FROM node:18-alpine3.18
WORKDIR /app
COPY www/ /app/www
COPY www/browser /app/www/browser
COPY package.json /app
EXPOSE 8100
RUN npm install -g http-server
CMD http-server www --p 8100
CMD http-server www/browser --p 8100

View File

@@ -11,12 +11,12 @@
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "zone.js",
"browser": "src/main.ts",
"polyfills": ["zone.js", "src/ion-icons.js"],
"tsConfig": "tsconfig.app.json",
"allowedCommonJsDependencies": [
"moment",
@@ -72,9 +72,7 @@
]
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true

View File

@@ -3,7 +3,7 @@ import {CapacitorConfig} from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'de.anyschool.app',
appName: 'StApps',
webDir: 'www',
webDir: 'www/browser',
cordova: {
preferences: {
'AndroidXEnabled': 'true',

View File

@@ -14,12 +14,9 @@
"Thea Schöbl <dev@theaninova.de>"
],
"scripts": {
"analyze": "webpack-bundle-analyzer www/stats.json",
"build": "pnpm check-icons && ng build --configuration=production --stats-json && webpack-bundle-analyzer www/stats.json --mode static --report www/bundle-info.html --no-open",
"build:analyze": "npm run build:stats && npm run analyze",
"build": "pnpm check-icons && ng build --configuration=production",
"build:android": "ionic capacitor build android --no-open && cd android && ./gradlew clean assemble && cd ..",
"build:prod": "ng build --configuration=production",
"build:stats": "ng build --configuration=production --stats-json",
"changelog": "conventional-changelog -p angular -i src/assets/about/CHANGELOG.md -s -r 0",
"check-icons": "node scripts/check-icon-correctness.mjs",
"chromium:no-cors": "chromium --disable-web-security --user-data-dir=\".browser-data/chromium\"",
@@ -40,7 +37,7 @@
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/ && stylelint --fix \"**/*.scss\"",
"minify-icons": "node scripts/minify-icon-font.mjs",
"postinstall": "jetify && echo \"skipping jetify in production mode\"",
"preview": "http-server www --p 8101 -o",
"preview": "http-server www/browser --p 8101 -o",
"push": "git push && git push origin \"v$npm_package_version\"",
"resources:ios": "capacitor-assets generate --ios --iconBackgroundColor $(grep -oE \"^@include ion-color\\(primary, #[a-fA-F0-9]{3,6}\" src/theme/colors.scss | grep -oE \"#[a-fA-F0-9]{3,6}\") --splashBackgroundColor $(grep -oE \"^@include ion-color\\(primary, #[a-fA-F0-9]{3,6}\" src/theme/colors.scss | grep -oE \"#[a-fA-F0-9]{3,6}\")",
"run:android": "ionic capacitor run android --livereload --external",
@@ -97,6 +94,7 @@
"form-data": "4.0.0",
"geojson": "0.5.0",
"ionic-appauth": "0.9.0",
"ionicons": "7.4.0",
"jsonpath-plus": "10.0.7",
"maplibre-gl": "4.0.2",
"material-symbols": "0.17.1",
@@ -181,8 +179,7 @@
"stylelint-config-standard-scss": "13.0.0",
"surge": "0.23.1",
"ts-node": "10.9.2",
"typescript": "5.4.2",
"webpack-bundle-analyzer": "4.10.1"
"typescript": "5.4.2"
},
"cordova": {
"plugins": {},

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {AnimationBuilder, AnimationController} from '@ionic/angular';
import {AnimationBuilder, AnimationController} from '@ionic/angular/standalone';
import {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
import {iosDuration, iosEasing, mdDuration, mdEasing} from './easings';

View File

@@ -17,7 +17,7 @@
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {TestBed} from '@angular/core/testing';
import {ModalController, Platform} from '@ionic/angular';
import {ModalController, Platform} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
import {ThingTranslateService} from './translation/thing-translate.service';

View File

@@ -15,7 +15,7 @@
import {AfterContentInit, Component, NgZone} from '@angular/core';
import {Router} from '@angular/router';
import {App, URLOpenListenerEvent} from '@capacitor/app';
import {Platform, ToastController} from '@ionic/angular';
import {Platform, ToastController} from '@ionic/angular/standalone';
import {SettingsProvider} from './modules/settings/settings.provider';
import {AuthHelperService} from './modules/auth/auth-helper.service';
import {environment} from '../environments/environment';

View File

@@ -18,7 +18,7 @@ import localeDe from '@angular/common/locales/de';
import {APP_INITIALIZER, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {RouteReuseStrategy} from '@angular/router';
import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular';
import {IonicRouteStrategy, Platform, provideIonicAngular, IonApp} from '@ionic/angular/standalone';
import {TranslateLoader, TranslateModule, TranslateService} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import moment from 'moment';
@@ -61,7 +61,6 @@ import {RoutingStackService} from './util/routing-stack.service';
import {SCLanguageCode, SCSettingValue} from '@openstapps/core';
import {DefaultAuthService} from './modules/auth/default-auth.service';
import {PAIAAuthService} from './modules/auth/paia/paia-auth.service';
import {IonIconModule} from './util/ion-icon/ion-icon.module';
import {NavigationModule} from './modules/menu/navigation/navigation.module';
import {browserFactory, SimpleBrowser} from './util/browser.factory';
import {getDateFnsLocale} from './translation/dfns-locale';
@@ -156,8 +155,6 @@ export function createTranslateLoader(http: HttpClient) {
DashboardModule,
DataModule,
HebisModule,
IonicModule.forRoot(),
IonIconModule,
JobModule,
FavoritesModule,
LibraryModule,
@@ -185,6 +182,7 @@ export function createTranslateLoader(http: HttpClient) {
LoggerModule.forRoot({
level: environment.production ? NgxLoggerLevel.FATAL : NgxLoggerLevel.TRACE,
}),
IonApp,
],
providers: [
{
@@ -221,6 +219,7 @@ export function createTranslateLoader(http: HttpClient) {
useClass: ServiceHandlerInterceptor,
multi: true,
},
provideIonicAngular(),
],
})
export class AppModule {

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, OnInit} from '@angular/core';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
import {AboutLicenseModalComponent} from './about-license-modal.component';
import licensesFile from 'src/assets/about/licenses.json';

View File

@@ -16,7 +16,6 @@ import {RouterModule, Routes} from '@angular/router';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {AboutPageComponent} from './about-page/about-page.component';
@@ -28,8 +27,31 @@ import {ScrollingModule} from '@angular/cdk/scrolling';
import {AboutLicenseModalComponent} from './about-license-modal.component';
import {AboutChangelogComponent} from './about-changelog.component';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {AboutReleaseNotesComponent} from './about-release-notes.component';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonChip,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonLabel,
IonList,
IonRouterLink,
IonRow,
IonSkeletonText,
IonText,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const settingsRoutes: Routes = [
{path: 'about', component: AboutPageComponent},
@@ -55,9 +77,8 @@ const settingsRoutes: Routes = [
],
imports: [
CommonModule,
IonIconModule,
IonIconDirective,
FormsModule,
IonicModule.forRoot(),
TranslateModule.forChild(),
ThingTranslateModule.forChild(),
RouterModule.forChild(settingsRoutes),
@@ -65,6 +86,27 @@ const settingsRoutes: Routes = [
DataModule,
ScrollingModule,
UtilModule,
IonRouterLink,
IonBackButton,
IonButton,
IonButtons,
IonText,
IonSkeletonText,
IonTitle,
IonToolbar,
IonHeader,
IonLabel,
IonGrid,
IonRow,
IonCol,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardContent,
IonCardSubtitle,
IonChip,
IonList,
IonContent,
],
})
export class AboutModule {}

View File

@@ -1,12 +1,12 @@
import {Injectable} from '@angular/core';
import {StorageProvider} from '../storage/storage.provider';
import {ConfigProvider} from '../config/config.provider';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
import {Capacitor} from '@capacitor/core';
import {ReleaseNotesComponent} from './release-notes.component';
import {SCAppVersionInfo} from '@openstapps/core';
import {App} from '@capacitor/app';
import {coerce} from 'semver';
import {Capacitor} from '@capacitor/core';
export const RELEASE_NOTES_SHOWN_KEY = 'release_notes_shown';

View File

@@ -2,7 +2,14 @@ import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {SCAppVersionInfo} from '@openstapps/core';
import {MarkdownModule} from 'ngx-markdown';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {IonicModule, ModalController} from '@ionic/angular';
import {
IonButton,
IonButtons,
IonHeader,
IonTitle,
IonToolbar,
ModalController,
} from '@ionic/angular/standalone';
import {TranslateModule} from '@ngx-translate/core';
import {UtilModule} from '../../util/util.module';
@@ -12,7 +19,17 @@ import {UtilModule} from '../../util/util.module';
styleUrls: ['release-notes.scss', 'release-notes-markdown.scss'],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [UtilModule, MarkdownModule, ThingTranslateModule, IonicModule, TranslateModule],
imports: [
UtilModule,
MarkdownModule,
ThingTranslateModule,
TranslateModule,
IonButton,
IonButtons,
IonToolbar,
IonHeader,
IonTitle,
],
})
export class ReleaseNotesComponent {
@Input() versionInfos: SCAppVersionInfo[];

View File

@@ -19,7 +19,6 @@ import {AssessmentBaseInfoComponent} from './types/assessment/assessment-base-in
import {AssessmentDetailComponent} from './types/assessment/assessment-detail.component';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {DataModule} from '../data/data.module';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
@@ -35,8 +34,25 @@ import {AssessmentsProvider} from './assessments.provider';
import {AssessmentsSimpleDataListComponent} from './list/assessments-simple-data-list.component';
import {ProtectedRoutes} from '../auth/protected.routes';
import {AssessmentsTreeListComponent} from './list/assessments-tree-list.component';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {UtilModule} from '../../util/util.module';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonContent,
IonHeader,
IonItem,
IonLabel,
IonList,
IonNote,
IonSegment,
IonSegmentButton,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const routes: ProtectedRoutes = [
{
@@ -69,14 +85,28 @@ const routes: ProtectedRoutes = [
imports: [
CommonModule,
FormsModule,
IonIconModule,
IonicModule,
IonIconDirective,
RouterModule.forChild(routes),
TranslateModule,
DataModule,
ThingTranslateModule,
MomentModule,
UtilModule,
IonBackButton,
IonList,
IonItem,
IonNote,
IonCardContent,
IonCard,
IonLabel,
IonSegment,
IonSegmentButton,
IonButtons,
IonTitle,
IonContent,
IonHeader,
IonToolbar,
IonButton,
],
providers: [AssessmentsProvider],
exports: [],

View File

@@ -17,7 +17,7 @@ import {Component, DestroyRef, inject, Input, OnInit, ViewChild} from '@angular/
import {ActivatedRoute} from '@angular/router';
import {AssessmentsProvider} from '../assessments.provider';
import {DataDetailComponent, ExternalDataLoadEvent} from '../../data/detail/data-detail.component';
import {NavController} from '@ionic/angular';
import {NavController} from '@ionic/angular/standalone';
import {DataRoutingService} from '../../data/data-routing.service';
import {SCAssessment} from '@openstapps/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component} from '@angular/core';
import {NavController} from '@ionic/angular';
import {NavController} from '@ionic/angular/standalone';
import {Router} from '@angular/router';
import {AuthActions, IAuthAction} from 'ionic-appauth';
import {AuthHelperService} from '../../auth-helper.service';

View File

@@ -29,7 +29,7 @@ import {StorageProvider} from '../storage/storage.provider';
import {DefaultAuthService} from './default-auth.service';
import {PAIAAuthService} from './paia/paia-auth.service';
import {SimpleBrowser} from '../../util/browser.factory';
import {AlertController} from '@ionic/angular';
import {AlertController} from '@ionic/angular/standalone';
const AUTH_ORIGIN_PATH = 'stapps.auth.origin_path';

View File

@@ -1,6 +1,6 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {Requestor, StorageBackend} from '@openid/appauth';
import {storageFactory} from './factories';
import {Browser} from 'ionic-appauth';

View File

@@ -14,7 +14,7 @@
*/
import {HttpClient} from '@angular/common/http';
import {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {CapacitorRequestor} from '../capacitor-requestor';
import {NgHttpService} from '../ng-http.service';

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {IonicStorage} from 'ionic-appauth/lib';
import {SafeCapacitorSecureStorage} from '../../storage/capacitor-secure-storage';

View File

@@ -67,7 +67,7 @@
<div class="horizontal-flex">
<ion-button fill="clear" (click)="export()">
{{ 'share' | translate }}
<ion-icon slot="end" md="share" ios="ios_share"></ion-icon>
<ion-icon slot="end" name="share"></ion-icon>
</ion-button>
@if (isWeb) {
<ion-button fill="outline" (click)="download()">

View File

@@ -18,26 +18,46 @@ import {AddEventReviewModalComponent} from './add-event-review-modal.component';
import {Calendar} from '@awesome-cordova-plugins/calendar/ngx';
import {CalendarService} from './calendar.service';
import {ScheduleProvider} from './schedule.provider';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {FormsModule} from '@angular/forms';
import {CommonModule} from '@angular/common';
import {MomentModule} from 'ngx-moment';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonButton,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonItem,
IonItemDivider,
IonItemGroup,
IonLabel,
IonList,
IonNote,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@NgModule({
declarations: [AddEventReviewModalComponent],
imports: [
IonicModule.forRoot(),
TranslateModule.forChild(),
ThingTranslateModule.forChild(),
IonIconModule,
IonIconDirective,
FormsModule,
CommonModule,
MomentModule,
UtilModule,
IonButton,
IonItem,
IonNote,
IonLabel,
IonList,
IonItemGroup,
IonItemDivider,
IonCardContent,
IonCardTitle,
IonCardHeader,
],
exports: [],
providers: [Calendar, CalendarService, ScheduleProvider],

View File

@@ -16,14 +16,29 @@ import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
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 {CatalogComponent} from './catalog.component';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonHeader,
IonToolbar,
IonButtons,
IonBackButton,
IonTitle,
IonSegment,
IonSegmentButton,
IonLabel,
IonContent,
IonList,
IonItem,
IonGrid,
IonRow,
IonCol,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const catalogRoutes: Routes = [
{path: 'catalog', component: CatalogComponent},
@@ -36,15 +51,28 @@ const catalogRoutes: Routes = [
@NgModule({
declarations: [CatalogComponent],
imports: [
IonicModule.forRoot(),
FormsModule,
TranslateModule.forChild(),
RouterModule.forChild(catalogRoutes),
IonIconModule,
IonIconDirective,
CommonModule,
MomentModule,
DataModule,
UtilModule,
IonHeader,
IonToolbar,
IonButtons,
IonBackButton,
IonTitle,
IonSegment,
IonSegmentButton,
IonLabel,
IonContent,
IonList,
IonItem,
IonGrid,
IonRow,
IonCol,
],
providers: [SettingsProvider],
})

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Animation, AnimationController} from '@ionic/angular';
import {Animation, AnimationController} from '@ionic/angular/standalone';
import {NgZone} from '@angular/core';
export class DashboardCollapse {

View File

@@ -118,10 +118,6 @@ ion-content {
font-weight: var(--font-weight-semi-bold);
word-break: break-word;
}
&:hover ::ng-deep stapps-icon {
--fill: 1;
}
}
a:last-child {
@@ -159,4 +155,8 @@ ion-content {
line-height: 1.2;
}
}
a:first-child:hover {
--fill: 1;
}
}

View File

@@ -29,7 +29,7 @@ import moment from 'moment';
import {SCDateSeries, SCUuid} from '@openstapps/core';
import {DataRoutingService} from '../data/data-routing.service';
import {ScheduleProvider} from '../calendar/schedule.provider';
import {AnimationController, IonContent} from '@ionic/angular';
import {AnimationController, IonContent} from '@ionic/angular/standalone';
import {DashboardCollapse} from './dashboard-collapse';
import {BreakpointObserver} from '@angular/cdk/layout';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
@@ -37,7 +37,7 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss', '/dashboard.collapse.component.scss'],
styleUrls: ['./dashboard.component.scss', './dashboard.collapse.component.scss'],
})
export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
@ViewChild('toolbar', {read: ElementRef}) toolbarRef: ElementRef;

View File

@@ -16,7 +16,6 @@ import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {SwiperModule} from 'swiper/angular';
import {TranslateModule, TranslatePipe} from '@ngx-translate/core';
import {MomentModule} from 'ngx-moment';
@@ -30,10 +29,23 @@ import {MensaSectionContentComponent} from './sections/mensa-section/mensa-secti
import {FavoritesSectionComponent} from './sections/favorites-section/favorites-section.component';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {NewsModule} from '../news/news.module';
import {JobSectionComponent} from './sections/jobs-section/job-section.component';
import {JobModule} from '../jobs/jobs.module';
import {
IonHeader,
IonToolbar,
IonLabel,
IonImg,
IonContent,
IonButton,
IonItem,
IonThumbnail,
IonSearchbar,
IonRippleEffect,
IonRouterLink,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const catalogRoutes: Routes = [
{
@@ -56,8 +68,7 @@ const catalogRoutes: Routes = [
JobSectionComponent,
],
imports: [
IonicModule.forRoot(),
IonIconModule,
IonIconDirective,
FormsModule,
TranslateModule.forChild(),
RouterModule.forChild(catalogRoutes),
@@ -69,6 +80,17 @@ const catalogRoutes: Routes = [
UtilModule,
NewsModule,
JobModule,
IonHeader,
IonToolbar,
IonImg,
IonContent,
IonButton,
IonItem,
IonLabel,
IonThumbnail,
IonSearchbar,
IonRippleEffect,
IonRouterLink,
],
providers: [SettingsProvider, TranslatePipe],
})

View File

@@ -35,4 +35,6 @@ export class JobSectionComponent {
from: 0,
})
.then((result: SCSearchResult) => result.data);
constructor() {}
}

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {AnimationController} from '@ionic/angular';
import {AnimationController} from '@ionic/angular/standalone';
import {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
/**

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component} from '@angular/core';
import {AnimationController} from '@ionic/angular';
import {AnimationController} from '@ionic/angular/standalone';
import {homePageSearchTransition} from './search-route-transition';
/**

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, DestroyRef, inject, Input, ViewChild} from '@angular/core';
import {IonRouterOutlet, ModalController} from '@ionic/angular';
import {IonRouterOutlet, ModalController} from '@ionic/angular/standalone';
import {SCDateSeries, SCThing, SCThingType, SCUuid} from '@openstapps/core';
import {Subscription} from 'rxjs';
import {ScheduleProvider} from '../../../calendar/schedule.provider';

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
import {SCDateSeries} from '@openstapps/core';
import {
DateSeriesRelevantData,

View File

@@ -13,6 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, EventEmitter, Input, Output} from '@angular/core';
/**
* Shows a chip filter
*/

View File

@@ -17,13 +17,55 @@ import {CommonModule} from '@angular/common';
import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {IonicModule, Platform} from '@ionic/angular';
import {
IonAccordion,
IonButton,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardContent,
IonAccordionGroup,
IonBreadcrumb,
IonBreadcrumbs,
IonButtons,
IonChip,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonImg,
IonLabel,
IonList,
IonListHeader,
IonNote,
IonPopover,
IonRow,
IonSegment,
IonSegmentButton,
IonText,
IonThumbnail,
IonToolbar,
Platform,
IonMenuButton,
IonSearchbar,
IonTitle,
IonBackButton,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonItem,
IonSkeletonText,
IonToast,
IonBadge,
IonCardSubtitle,
IonCheckbox,
IonFooter,
IonRouterLink,
} from '@ionic/angular/standalone';
import {TranslateModule} from '@ngx-translate/core';
import {MarkdownModule} from 'ngx-markdown';
import {MomentModule} from 'ngx-moment';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {SimpleBrowser, browserFactory} from '../../util/browser.factory';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {RoutingStackService} from '../../util/routing-stack.service';
import {UtilModule} from '../../util/util.module';
import {CalendarService} from '../calendar/calendar.service';
@@ -106,6 +148,7 @@ import {SemesterListItemComponent} from './types/semester/semester-list-item.com
import {VideoDetailContentComponent} from './types/video/video-detail-content.component';
import {VideoListItemComponent} from './types/video/video-list-item.component';
import {ShareButtonComponent} from './elements/share-button.component';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
/**
* Module for handling data
@@ -187,10 +230,9 @@ import {ShareButtonComponent} from './elements/share-button.component';
FormsModule,
MapWidgetComponent,
HttpClientModule,
IonicModule.forRoot(),
MarkdownModule.forRoot(),
MenuModule,
IonIconModule,
IonIconDirective,
MomentModule.forRoot({
relativeTimeThresholdOptions: {
m: 59,
@@ -202,6 +244,47 @@ import {ShareButtonComponent} from './elements/share-button.component';
ThingTranslateModule.forChild(),
UtilModule,
GeoNavigationDirective,
IonButton,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardContent,
IonCardSubtitle,
IonNote,
IonLabel,
IonGrid,
IonCol,
IonRow,
IonList,
IonSegment,
IonListHeader,
IonSegmentButton,
IonChip,
IonImg,
IonPopover,
IonThumbnail,
IonBreadcrumbs,
IonBreadcrumb,
IonAccordion,
IonAccordionGroup,
IonText,
IonContent,
IonButtons,
IonHeader,
IonToolbar,
IonMenuButton,
IonSearchbar,
IonTitle,
IonBackButton,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonItem,
IonSkeletonText,
IonToast,
IonBadge,
IonCheckbox,
IonFooter,
IonRouterLink,
],
providers: [
CoordinatedSearchProvider,

View File

@@ -14,7 +14,7 @@
*/
import {Injectable} from '@angular/core';
import {SCFeedbackRequestMetaData} from '@openstapps/core';
import {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {DataProvider} from './data.provider';
import {NavigationEnd, Router} from '@angular/router';
import {SettingsProvider} from '../settings/settings.provider';

View File

@@ -15,7 +15,7 @@
import {Component, Input, TemplateRef} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {DataListContext} from '../list/data-list.component';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
/**
* TODO

View File

@@ -26,6 +26,7 @@ import {DataDetailComponent} from './data-detail.component';
import {Observable, of} from 'rxjs';
import {StorageProvider} from '../../storage/storage.provider';
import {LoggerModule, NgxLoggerLevel} from 'ngx-logger';
import {provideIonicAngular} from '@ionic/angular/standalone';
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
@@ -71,6 +72,7 @@ describe('DataDetailComponent', () => {
LoggerModule.forRoot({level: NgxLoggerLevel.TRACE}),
],
providers: [
provideIonicAngular(),
{
provide: ActivatedRoute,
useValue: fakeActivatedRoute,

View File

@@ -14,7 +14,7 @@
*/
import {Component, ContentChild, EventEmitter, Input, OnInit, Output, TemplateRef} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {SCLanguageCode, SCSaveableThing, SCThings, SCUuid} from '@openstapps/core';
import {DataProvider, DataScope} from '../data.provider';

View File

@@ -19,7 +19,7 @@ import {DataProvider, DataScope} from '../data.provider';
import {fromEvent, Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import {DataRoutingService} from '../data-routing.service';
import {NavController} from '@ionic/angular';
import {NavController} from '@ionic/angular/standalone';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
@Component({

View File

@@ -18,7 +18,6 @@ ion-button {
--background-hover: currentcolor;
--background-focused: currentcolor;
aspect-ratio: 1;
color: inherit;
}
@@ -27,7 +26,7 @@ ion-button {
}
@media (hover: hover) {
ion-button:hover ::ng-deep stapps-icon {
ion-button:hover > ion-icon {
--fill: 1 !important;
}
}

View File

@@ -15,7 +15,7 @@
ion-button {
margin: 0;
&.button-disabled::ng-deep stapps-icon {
&.button-disabled {
--fill: 1;
}
}
@@ -39,17 +39,17 @@ ion-button {
border-radius: var(--border-radius-default);
> ion-icon {
&:active::ng-deep stapps-icon,
&:has(:checked)::ng-deep stapps-icon,
&:has(:checked)::ng-deep ~ *::ng-deep stapps-icon,
&:active::ng-deep ~ *::ng-deep stapps-icon {
&:active,
&:has(:checked),
&:has(:checked) ~ *,
&:active ~ * {
--fill: 1;
color: var(--ion-color-dark);
}
@media (hover: hover) {
&:hover ~ *::ng-deep stapps-icon,
&:hover::ng-deep stapps-icon {
&:hover ~ *,
&:hover {
--fill: 1;
}
}

View File

@@ -1,5 +1,5 @@
import {Component, Input} from '@angular/core';
import {ToastController} from '@ionic/angular';
import {ToastController} from '@ionic/angular/standalone';
import {environment} from '../../../../environments/environment';
@Component({

View File

@@ -29,7 +29,7 @@ import {
} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {IonInfiniteScroll} from '@ionic/angular';
import {IonInfiniteScroll} from '@ionic/angular/standalone';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
export interface DataListContext<T> {

View File

@@ -13,8 +13,8 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import type {AnimationBuilder} from '@ionic/angular';
import {AnimationController} from '@ionic/angular';
import type {AnimationBuilder} from '@ionic/angular/standalone';
import {AnimationController} from '@ionic/angular/standalone';
import type {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
/**

View File

@@ -15,7 +15,7 @@
import {Component, DestroyRef, inject, Input, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Keyboard} from '@capacitor/keyboard';
import {AlertController, AnimationBuilder, AnimationController} from '@ionic/angular';
import {AlertController, AnimationBuilder, AnimationController} from '@ionic/angular/standalone';
import {Capacitor} from '@capacitor/core';
import {
SCFacet,

View File

@@ -16,7 +16,7 @@ import {AfterViewInit, Component, DestroyRef, inject, Input} from '@angular/core
import {SCDish, SCISO8601Date, SCPlace} from '@openstapps/core';
import {PlaceMensaService} from './place-mensa-service';
import {Router} from '@angular/router';
import {IonRouterOutlet} from '@ionic/angular';
import {IonRouterOutlet} from '@ionic/angular/standalone';
import {DataRoutingService} from '../../../../data-routing.service';
import {groupBy} from '@openstapps/collection-utils';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, OnInit} from '@angular/core';
import {AlertController, AnimationController} from '@ionic/angular';
import {AlertController, AnimationController} from '@ionic/angular/standalone';
import {ActivatedRoute, Router} from '@angular/router';
import {NGXLogger} from 'ngx-logger';
import {debounceTime, distinctUntilChanged, startWith, take} from 'rxjs/operators';

View File

@@ -15,14 +15,25 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {FavoritesPageComponent} from './favorites-page.component';
import {RouterModule, Routes} from '@angular/router';
import {MenuModule} from '../menu/menu.module';
import {TranslateModule} from '@ngx-translate/core';
import {DataModule} from '../data/data.module';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonBackButton,
IonButton,
IonButtons,
IonContent,
IonHeader,
IonLabel,
IonMenuButton,
IonSearchbar,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const favoritesRoutes: Routes = [
{
@@ -35,13 +46,22 @@ const favoritesRoutes: Routes = [
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(favoritesRoutes),
MenuModule,
TranslateModule,
DataModule,
IonIconModule,
IonIconDirective,
UtilModule,
IonLabel,
IonHeader,
IonToolbar,
IonButtons,
IonContent,
IonButton,
IonMenuButton,
IonSearchbar,
IonTitle,
IonBackButton,
],
declarations: [FavoritesPageComponent],
})

View File

@@ -23,7 +23,7 @@ import {
} from '@openstapps/core';
import {DataProvider} from '../data/data.provider';
import {DebugDataCollectorService} from '../data/debug-data-collector.service';
import {AlertController, ToastController} from '@ionic/angular';
import {AlertController, ToastController} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
@Component({

View File

@@ -15,13 +15,30 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {FeedbackPageComponent} from './feedback-page.component';
import {RouterModule, Routes} from '@angular/router';
import {TranslateModule} from '@ngx-translate/core';
import {MarkdownModule} from 'ngx-markdown';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardTitle,
IonCheckbox,
IonHeader,
IonInput,
IonItem,
IonLabel,
IonSelect,
IonSelectOption,
IonTextarea,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const feedbackRoutes: Routes = [
{
@@ -34,12 +51,27 @@ const feedbackRoutes: Routes = [
imports: [
CommonModule,
FormsModule,
IonicModule,
IonIconModule,
IonIconDirective,
RouterModule.forChild(feedbackRoutes),
TranslateModule,
MarkdownModule,
UtilModule,
IonBackButton,
IonCard,
IonCardContent,
IonButton,
IonItem,
IonLabel,
IonCardTitle,
IonCheckbox,
IonTextarea,
IonInput,
IonSelect,
IonSelectOption,
IonTitle,
IonButtons,
IonToolbar,
IonHeader,
],
declarations: [FeedbackPageComponent],
})

View File

@@ -27,6 +27,7 @@ import {StorageProvider} from '../../storage/storage.provider';
import {DaiaDataProvider} from '../daia-data.provider';
import {ConfigProvider} from '../../config/config.provider';
import {LoggerTestingModule} from 'ngx-logger/testing';
import {provideIonicAngular} from '@ionic/angular/standalone';
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
@@ -74,6 +75,7 @@ describe('DaiaAvailabilityComponent', () => {
LoggerTestingModule,
],
providers: [
provideIonicAngular(),
{
provide: ActivatedRoute,
useValue: fakeActivatedRoute,

View File

@@ -37,6 +37,6 @@ ion-grid {
}
}
ion-icon ::ng-deep stapps-icon {
ion-icon {
--fill: 1;
}

View File

@@ -26,9 +26,9 @@ import {HebisDataProvider} from '../hebis-data.provider';
import {HebisDetailComponent} from './hebis-detail.component';
import {Observable, of} from 'rxjs';
import {StorageProvider} from '../../storage/storage.provider';
import {IonicModule} from '@ionic/angular';
import {IonIconModule} from '../../../util/ion-icon/ion-icon.module';
import {LoggerModule, NgxLoggerLevel} from 'ngx-logger';
import {IonIconDirective} from '../../../util/ion-icon/ion-icon.directive';
import {provideIonicAngular} from '@ionic/angular/standalone';
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
@@ -68,14 +68,14 @@ describe('HebisDetailComponent', () => {
RouterModule.forRoot([]),
HebisRoutingModule,
HebisModule,
IonicModule,
IonIconModule,
IonIconDirective,
TranslateModule.forRoot({
loader: {provide: TranslateLoader, useClass: TranslateFakeLoader},
}),
LoggerModule.forRoot({level: NgxLoggerLevel.TRACE}),
],
providers: [
provideIonicAngular(),
{
provide: ActivatedRoute,
useValue: fakeActivatedRoute,

View File

@@ -17,7 +17,6 @@ import {CommonModule} from '@angular/common';
import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {MarkdownModule} from 'ngx-markdown';
import {MomentModule} from 'ngx-moment';
@@ -34,8 +33,27 @@ import {HebisRoutingModule} from './hebis-routing.module';
import {DataModule} from '../data/data.module';
import {DaiaAvailabilityComponent} from './daia-availability/daia-availability.component';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {DaiaHoldingComponent} from './daia-availability/daia-holding.component';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonItem,
IonLabel,
IonNote,
IonRow,
IonThumbnail,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
/**
* Module for handling data
@@ -53,9 +71,8 @@ import {DaiaHoldingComponent} from './daia-availability/daia-holding.component';
DataModule,
FormsModule,
HebisRoutingModule,
IonIconModule,
IonIconDirective,
HttpClientModule,
IonicModule.forRoot(),
MarkdownModule.forRoot(),
MenuModule,
MomentModule.forRoot({
@@ -68,6 +85,23 @@ import {DaiaHoldingComponent} from './daia-availability/daia-holding.component';
TranslateModule.forChild(),
ThingTranslateModule.forChild(),
UtilModule,
IonBackButton,
IonLabel,
IonButton,
IonContent,
IonButtons,
IonTitle,
IonToolbar,
IonNote,
IonHeader,
IonGrid,
IonRow,
IonCol,
IonCard,
IonCardContent,
IonCardHeader,
IonItem,
IonThumbnail,
],
providers: [HebisDataProvider, DaiaDataProvider, StAppsWebHttpClient],
})

View File

@@ -1,25 +1,23 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {MomentModule} from 'ngx-moment';
import {DataModule} from '../data/data.module';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {RouterModule, Routes} from '@angular/router';
import {JobsPageComponent} from './page/jobs-page.component';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const jobsRoutes: Routes = [{path: 'jobs', component: JobsPageComponent}];
@NgModule({
declarations: [JobsPageComponent],
imports: [
IonicModule.forRoot(),
ThingTranslateModule.forChild(),
TranslateModule.forChild(),
RouterModule.forChild(jobsRoutes),
IonIconModule,
IonIconDirective,
CommonModule,
MomentModule,
DataModule,

View File

@@ -34,7 +34,7 @@ import {PAIATokenResponse} from '../../auth/paia/paia-token-response';
import {AuthHelperService} from '../../auth/auth-helper.service';
import {ConfigProvider} from '../../config/config.provider';
import {TranslateService} from '@ngx-translate/core';
import {AlertController, ToastController} from '@ionic/angular';
import {AlertController, ToastController} from '@ionic/angular/standalone';
import {HebisSearchResponse} from '../../hebis/protocol/response';
@Injectable({

View File

@@ -16,7 +16,6 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {IonicModule} from '@ionic/angular';
import {RouterModule, Routes} from '@angular/router';
import {TranslateModule} from '@ngx-translate/core';
import {LibraryAccountPageComponent} from './account/account.page';
@@ -32,7 +31,28 @@ import {MomentModule} from 'ngx-moment';
import {FeeItemComponent} from './account/elements/fee-item/fee-item.component';
import {DataModule} from '../data/data.module';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonHeader,
IonToolbar,
IonButtons,
IonBackButton,
IonTitle,
IonContent,
IonSkeletonText,
IonItem,
IonGrid,
IonCol,
IonRow,
IonLabel,
IonCard,
IonCardContent,
IonList,
IonSegment,
IonSegmentButton,
IonButton,
IonBadge,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const routes: ProtectedRoutes | Routes = [
{
@@ -71,13 +91,31 @@ const routes: ProtectedRoutes | Routes = [
imports: [
CommonModule,
FormsModule,
IonicModule,
IonIconModule,
IonIconDirective,
RouterModule.forChild(routes),
TranslateModule,
MomentModule,
DataModule,
UtilModule,
IonHeader,
IonBadge,
IonToolbar,
IonButtons,
IonBackButton,
IonTitle,
IonContent,
IonSkeletonText,
IonItem,
IonGrid,
IonCol,
IonRow,
IonLabel,
IonCard,
IonCardContent,
IonList,
IonSegment,
IonSegmentButton,
IonButton,
],
declarations: [
LibraryAccountPageComponent,

View File

@@ -1,10 +1,10 @@
import {animate, style, transition, trigger} from '@angular/animations';
import {AsyncPipe} from '@angular/common';
import {ChangeDetectionStrategy, Component, Input, inject} from '@angular/core';
import {IonicModule} from '@ionic/angular';
import {IonButton} from '@ionic/angular/standalone';
import {MapService} from '@maplibre/ngx-maplibre-gl';
import {map, delay, Subject, race, mergeWith} from 'rxjs';
import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@Component({
selector: 'stapps-map-attribution',
@@ -12,7 +12,7 @@ import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
styleUrl: './attribution.scss',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [IonicModule, IonIconModule, AsyncPipe],
imports: [IonIconDirective, AsyncPipe, IonButton],
animations: [
trigger('fade', [
transition(':enter', [

View File

@@ -1,10 +1,10 @@
import {AsyncPipe} from '@angular/common';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {IonicModule} from '@ionic/angular';
import {IonFabButton} from '@ionic/angular/standalone';
import {MapService} from '@maplibre/ngx-maplibre-gl';
import {MapEventType} from 'maplibre-gl';
import {map, mergeMap, fromEventPattern, merge} from 'rxjs';
import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@Component({
selector: 'stapps-compass-control',
@@ -12,7 +12,7 @@ import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
styleUrl: './compass-control.scss',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [AsyncPipe, IonicModule, IonIconModule],
imports: [AsyncPipe, IonIconDirective, IonFabButton],
})
export class CompassControlComponent {
transform = this.mapService.mapCreated$.pipe(

View File

@@ -8,12 +8,12 @@ import {
OnDestroy,
ViewChild,
} from '@angular/core';
import {IonicModule} from '@ionic/angular';
import {IonFabButton} from '@ionic/angular/standalone';
import {MapService} from '@maplibre/ngx-maplibre-gl';
import {FitBoundsOptions, GeolocateControl, GeolocateControlOptions} from 'maplibre-gl';
import {Map as MapLibre} from 'maplibre-gl';
import {BehaviorSubject} from 'rxjs';
import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
type WatchState = InstanceType<typeof GeolocateControl>['_watchState'];
@@ -52,7 +52,7 @@ class CustomGeolocateControl extends GeolocateControl {
styleUrl: './geolocate-control.scss',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [AsyncPipe, IonicModule, IonIconModule],
imports: [AsyncPipe, IonIconDirective, IonFabButton],
})
export class GeolocateControlComponent implements AfterContentInit, OnDestroy {
@Input() position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

View File

@@ -1,12 +1,12 @@
import {ChangeDetectionStrategy, Component, HostBinding, Input, OnInit, Optional} from '@angular/core';
import {IonicModule} from '@ionic/angular';
import {IonIconModule} from 'src/app/util/ion-icon/ion-icon.module';
import {MapIconDirective} from '../map-icon.directive';
import {Feature, Point} from 'geojson';
import {SCFeatureProperties} from '../feature-collection.pipe';
import {MapDataProvider} from '../map-data.provider';
import {DataRoutingService} from '../../data/data-routing.service';
import {AddWordBreakOpportunitiesPipe} from '../../../util/word-break-opportunities.pipe';
import {IonButton, IonLabel} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@Component({
selector: 'stapps-poi-marker',
@@ -14,7 +14,7 @@ import {AddWordBreakOpportunitiesPipe} from '../../../util/word-break-opportunit
styleUrl: './poi-marker.scss',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [IonicModule, IonIconModule, MapIconDirective, AddWordBreakOpportunitiesPipe],
imports: [IonIconDirective, MapIconDirective, AddWordBreakOpportunitiesPipe, IonLabel, IonButton],
})
export class PoiMarkerComponent implements OnInit {
@Input({required: true}) feature: Feature<Point, SCFeatureProperties>;

View File

@@ -1,7 +1,7 @@
import {Directive, HostListener, Input} from '@angular/core';
import {SCPlaceWithoutReferences, SCThings, SCThingWithoutReferences} from '@openstapps/core';
import {Device} from '@capacitor/device';
import {ActionSheetController, ActionSheetOptions, ToastController} from '@ionic/angular';
import {ActionSheetController, ActionSheetOptions, ToastController} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
import {ThingTranslateService} from '../../translation/thing-translate.service';
import {Clipboard} from '@capacitor/clipboard';

View File

@@ -12,8 +12,8 @@
* 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 type {AnimationBuilder} from '@ionic/angular';
import {AnimationController} from '@ionic/angular';
import type {AnimationBuilder} from '@ionic/angular/standalone';
import {AnimationController} from '@ionic/angular/standalone';
import type {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
import {iosDuration, iosEasing, mdDuration, mdEasing} from 'src/app/animation/easings';

View File

@@ -13,7 +13,6 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {IonicModule} from '@ionic/angular';
import {LngLatBoundsLike, MapLibreEvent} from 'maplibre-gl';
import {
ControlComponent,
@@ -28,7 +27,6 @@ import {MediaQueryPipe} from '../../util/media-query.pipe';
import {MapStyleDirective} from './map-style.directive';
import {DataProvider} from '../data/data.provider';
import {SCSearchFilter, SCThingType} from '@openstapps/core';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {DataModule} from '../data/data.module';
import {AsyncPipe} from '@angular/common';
import {GeolocateControlComponent} from './controls/geolocate-control.component';
@@ -40,6 +38,8 @@ import {BuildingMarkersComponent} from './elements/building-markers.component';
import {PoiMarkersComponent} from './elements/poi-markers.component';
import {AttributionComponent} from './controls/attribution.component';
import {filter, map} from 'rxjs';
import {IonButton, IonContent, IonLabel, IonRouterLink} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
/**
* The main page of the map
@@ -65,8 +65,7 @@ import {filter, map} from 'rxjs';
DataModule,
GeolocateControlComponent,
GeolocateControlDirective,
IonIconModule,
IonicModule,
IonIconDirective,
MapAuto3dDirective,
MapComponent,
MapSizeFixDirective,
@@ -78,6 +77,10 @@ import {filter, map} from 'rxjs';
ThingPoiFeatureCollectionPipe,
ThingPolygonFeatureCollectionPipe,
TranslateModule,
IonContent,
IonLabel,
IonRouterLink,
IonButton,
],
})
export class MapPageComponent {

View File

@@ -15,11 +15,10 @@
import {ChangeDetectionStrategy, Component, HostBinding, Input, inject} from '@angular/core';
import {RouterLink} from '@angular/router';
import {ControlComponent, MapComponent, MarkerComponent} from '@maplibre/ngx-maplibre-gl';
import {AnimationController, IonicModule} from '@ionic/angular';
import {AnimationController, IonRouterLink} from '@ionic/angular/standalone';
import {GeoNavigationDirective} from './geo-navigation.directive';
import {TranslateModule} from '@ngx-translate/core';
import {CommonModule} from '@angular/common';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {MapAuto3dDirective} from './map-auto-3d.directive';
import {MediaQueryPipe} from 'src/app/util/media-query.pipe';
import {MapStyleDirective} from './map-style.directive';
@@ -31,6 +30,7 @@ import {BuildingMarkersComponent} from './elements/building-markers.component';
import {ThingBoundsPipe} from './thing-bounds.pipe';
import {AttributionComponent} from './controls/attribution.component';
import {mapMaximizeAnimation} from './map-maximize-animation';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
/**
* The map widget (needs a container with explicit size)
@@ -47,8 +47,7 @@ import {mapMaximizeAnimation} from './map-maximize-animation';
CommonModule,
ControlComponent,
GeoNavigationDirective,
IonIconModule,
IonicModule,
IonIconDirective,
MapAuto3dDirective,
MapComponent,
MapSizeFixDirective,
@@ -61,6 +60,7 @@ import {mapMaximizeAnimation} from './map-maximize-animation';
ThingPoiFeatureCollectionPipe,
ThingPolygonFeatureCollectionPipe,
TranslateModule,
IonRouterLink,
],
})
export class MapWidgetComponent {

View File

@@ -17,7 +17,6 @@ import {APP_BASE_HREF, CommonModule, Location, LocationStrategy, PathLocationStr
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from '@angular/forms';
import {ChildrenOutletContexts, RouterModule, UrlSerializer} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {SCFacet, SCThingType} from '@openstapps/core';
import {ContextMenuComponent} from './context-menu.component';
@@ -26,6 +25,7 @@ import {ContextMenuService} from './context-menu.service';
import {FilterContext, SortContext} from './context-type';
import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';
import {provideIonicAngular} from '@ionic/angular/standalone';
@Component({
template: `<ion-content id="foo"></ion-content><stapps-context contentId="foo"></stapps-context> `,
@@ -40,6 +40,7 @@ describe('ContextMenuComponent', async () => {
TestBed.configureTestingModule({
declarations: [ContextMenuComponent, ContextMenuContainerComponent],
providers: [
provideIonicAngular(),
ChildrenOutletContexts,
Location,
UrlSerializer,
@@ -49,7 +50,6 @@ describe('ContextMenuComponent', async () => {
],
imports: [
FormsModule,
IonicModule.forRoot(),
TranslateModule.forRoot(),
CommonModule,
SettingsModule,

View File

@@ -50,7 +50,7 @@
</ion-list>
<!-- Filter Context -->
@if (filterOption) {
<div class="context-filter">
<form class="context-filter">
<ion-list-header>
<ion-icon name="filter_list"></ion-icon>
<ion-title>{{ 'menu.context.filter.title' | translate | titlecase }}</ion-title>
@@ -80,6 +80,7 @@
<ion-checkbox
[(ngModel)]="bucket.checked"
(ngModelChange)="filterChanged()"
[name]="facet.onlyOnType + '-' + facet.field + '-' + bucket.key"
[value]="{
field: facet.field,
value: bucket.key,
@@ -107,7 +108,7 @@
</div>
</ion-list>
}
</div>
</form>
}
</ion-content>
</ion-menu>

View File

@@ -17,12 +17,28 @@ import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {LayoutModule} from '@angular/cdk/layout';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {SettingsModule} from '../settings/settings.module';
import {ContextMenuComponent} from './context/context-menu.component';
import {ContextMenuService} from './context/context-menu.service';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonButton,
IonCheckbox,
IonContent,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonMenu,
IonMenuToggle,
IonRadio,
IonRadioGroup,
IonTabBar,
IonTabButton,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
/**
* Menu module
@@ -32,13 +48,27 @@ import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
exports: [ContextMenuComponent],
imports: [
CommonModule,
IonIconModule,
IonIconDirective,
FormsModule,
IonicModule.forRoot(),
RouterModule,
SettingsModule,
TranslateModule.forChild(),
LayoutModule,
IonLabel,
IonTabButton,
IonTabBar,
IonMenu,
IonMenuToggle,
IonButton,
IonCheckbox,
IonItem,
IonList,
IonListHeader,
IonTitle,
IonRadio,
IonRadioGroup,
IonContent,
IonToolbar,
],
providers: [ContextMenuService],
})

View File

@@ -17,15 +17,49 @@ import {RootLinkDirective} from './root-link.directive';
import {NavigationComponent} from './navigation.component';
import {TabsComponent} from './tabs.component';
import {CommonModule} from '@angular/common';
import {IonicModule} from '@ionic/angular';
import {IonIconModule} from '../../../util/ion-icon/ion-icon.module';
import {TranslateModule} from '@ngx-translate/core';
import {RouterModule} from '@angular/router';
import {OfflineNoticeComponent} from './offline-notice.component';
import {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonImg,
IonLabel,
IonList,
IonMenu,
IonMenuToggle,
IonRouterOutlet,
IonSplitPane,
IonTabBar,
IonTabButton,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@NgModule({
declarations: [RootLinkDirective, NavigationComponent, TabsComponent, OfflineNoticeComponent],
imports: [CommonModule, IonicModule, IonIconModule, TranslateModule, RouterModule],
imports: [
CommonModule,
IonIconDirective,
TranslateModule,
RouterModule,
IonLabel,
IonTabBar,
IonTabButton,
IonMenuToggle,
IonButton,
IonRouterOutlet,
IonList,
IonContent,
IonImg,
IonButtons,
IonHeader,
IonMenu,
IonToolbar,
IonSplitPane,
],
exports: [TabsComponent, RootLinkDirective, NavigationComponent],
})
export class NavigationModule {}

View File

@@ -77,9 +77,7 @@ ion-router-outlet {
}
.link-active > * {
color: var(--ion-color-primary);
--fill: 1;
::ng-deep stapps-icon {
--fill: 1;
}
color: var(--ion-color-primary);
}

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {DestroyRef, Directive, ElementRef, inject, Input, OnInit, Renderer2} from '@angular/core';
import {AnimationController, NavController} from '@ionic/angular';
import {AnimationController, NavController} from '@ionic/angular/standalone';
import {Router, RouterEvent} from '@angular/router';
import {tabsTransition} from './tabs-transition';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

View File

@@ -13,8 +13,8 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import type {AnimationBuilder} from '@ionic/angular';
import {AnimationController} from '@ionic/angular';
import type {AnimationBuilder} from '@ionic/angular/standalone';
import {AnimationController} from '@ionic/angular/standalone';
import type {AnimationOptions} from '@ionic/angular/common/providers/nav-controller';
import {iosDuration, iosEasing, mdDuration, mdEasing} from 'src/app/animation/easings';

View File

@@ -60,6 +60,6 @@
}
}
.tab-selected ::ng-deep stapps-icon {
.tab-selected {
--fill: 1;
}

View File

@@ -23,7 +23,7 @@ import {ConfigProvider} from '../../config/config.provider';
import {sampleAuthConfiguration} from '../../../_helpers/data/sample-configuration';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import {NGXLogger} from 'ngx-logger';
import {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {ThingTranslateService} from '../../../translation/thing-translate.service';
import {SettingsProvider} from '../../settings/settings.provider';
import {ScheduleSyncService} from '../../background/schedule/schedule-sync.service';

View File

@@ -15,7 +15,6 @@
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 {ThingTranslateModule} from '../../translation/thing-translate.module';
@@ -28,7 +27,30 @@ import {ChipFilterComponent} from '../data/chips/filter/chip-filter.component';
import {SettingsModule} from '../settings/settings.module';
import {NewsSettingsFilterComponent} from './elements/news-filter-settings/news-settings-filter.component';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonBackButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonChip,
IonCol,
IonGrid,
IonHeader,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonLabel,
IonRefresher,
IonRefresherContent,
IonRouterLink,
IonRow,
IonSkeletonText,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const newsRoutes: Routes = [{path: 'news', component: NewsPageComponent}];
@@ -44,17 +66,37 @@ const newsRoutes: Routes = [{path: 'news', component: NewsPageComponent}];
NewsSettingsFilterComponent,
],
imports: [
IonicModule.forRoot(),
ThingTranslateModule.forChild(),
TranslateModule.forChild(),
RouterModule.forChild(newsRoutes),
IonIconModule,
IonIconDirective,
CommonModule,
MomentModule,
DataModule,
ThingTranslateModule,
SettingsModule,
UtilModule,
IonRouterLink,
IonBackButton,
IonChip,
IonLabel,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonGrid,
IonCol,
IonRow,
IonRefresher,
IonRefresherContent,
IonHeader,
IonToolbar,
IonButtons,
IonTitle,
IonSkeletonText,
IonCard,
IonCardContent,
IonCardTitle,
IonCardSubtitle,
IonCardHeader,
],
providers: [SettingsProvider],
exports: [NewsItemComponent],

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, OnInit} from '@angular/core';
import {IonRefresher} from '@ionic/angular';
import {IonRefresher} from '@ionic/angular/standalone';
import {SCMessage, SCSearchFilter, SCSearchValueFilter, SCSetting} from '@openstapps/core';
import {NewsProvider} from '../news.provider';

View File

@@ -12,7 +12,7 @@
* 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 'src/theme/util/mixins';
@import '../../../../theme/util/mixins';
.news-grid {
@include auto-grid(300px);

View File

@@ -4,7 +4,7 @@ import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {AsyncPipe, TitleCasePipe} from '@angular/common';
import {IntervalIsNowPipe, ToDateIntervalPipe} from '../../util/in-range.pipe';
import {TranslateModule} from '@ngx-translate/core';
import {AnimationController, ModalController} from '@ionic/angular';
import {AnimationController, ModalController} from '@ionic/angular/standalone';
import {ScreenBrightness} from '@capacitor-community/screen-brightness';
import {ScreenOrientation} from '@capacitor/screen-orientation';
import {Capacitor} from '@capacitor/core';

View File

@@ -15,13 +15,13 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {IdCardsProvider} from './id-cards.provider';
import {SCIdCard} from '@openstapps/core';
import {IonicModule} from '@ionic/angular';
import {AsyncPipe, TitleCasePipe} from '@angular/common';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {UtilModule} from '../../util/util.module';
import {IdCardComponent} from './id-card.component';
import {TranslateModule} from '@ngx-translate/core';
import {Observable} from 'rxjs';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
@Component({
selector: 'stapps-id-cards',
@@ -31,13 +31,13 @@ import {Observable} from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
IonicModule,
AsyncPipe,
ThingTranslateModule,
UtilModule,
IdCardComponent,
TranslateModule,
TitleCasePipe,
IonIconDirective,
],
})
export class IdCardsComponent {

View File

@@ -16,18 +16,38 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {ProfilePageComponent} from './page/profile-page.component';
import {TranslateModule} from '@ngx-translate/core';
import {SwiperModule} from 'swiper/angular';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {ProfilePageSectionComponent} from './page/profile-page-section.component';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {DataModule} from '../data/data.module';
import {MyCoursesComponent} from './page/my-courses.component';
import {MomentModule} from 'ngx-moment';
import {IdCardsComponent} from './id-cards.component';
import {
IonAccordion,
IonAccordionGroup,
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCol,
IonGrid,
IonHeader,
IonItem,
IonItemDivider,
IonItemGroup,
IonLabel,
IonList,
IonRouterLink,
IonRow,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const routes: Routes = [
{
@@ -41,8 +61,7 @@ const routes: Routes = [
imports: [
CommonModule,
FormsModule,
IonIconModule,
IonicModule,
IonIconDirective,
RouterModule.forChild(routes),
TranslateModule,
SwiperModule,
@@ -51,6 +70,25 @@ const routes: Routes = [
DataModule,
MomentModule,
IdCardsComponent,
IonRouterLink,
IonBackButton,
IonTitle,
IonButtons,
IonToolbar,
IonHeader,
IonLabel,
IonGrid,
IonRow,
IonCol,
IonCard,
IonCardContent,
IonItem,
IonButton,
IonItemGroup,
IonItemDivider,
IonList,
IonAccordion,
IonAccordionGroup,
],
})
export class ProfilePageModule {}

View File

@@ -21,7 +21,7 @@ import {ScheduleProvider} from '../../calendar/schedule.provider';
import {CalendarComponent} from './components/calendar.component';
import {CalendarService} from '../../calendar/calendar.service';
import {InfiniteSwiperComponent} from './grid/infinite-swiper.component';
import {IonContent} from '@ionic/angular';
import {IonContent} from '@ionic/angular/standalone';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
/**

View File

@@ -21,7 +21,7 @@ import {ScheduleProvider} from '../../../calendar/schedule.provider';
import {ScheduleEvent, ScheduleResponsiveBreakpoint} from '../schema/schema';
import {SwiperComponent} from 'swiper/angular';
import {InfiniteSwiperComponent} from '../grid/infinite-swiper.component';
import {IonContent, IonDatetime} from '@ionic/angular';
import {IonContent, IonDatetime} from '@ionic/angular/standalone';
import {CalendarService} from '../../../calendar/calendar.service';
import {getScheduleCursorOffset} from '../grid/schedule-cursor-offset';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

View File

@@ -15,7 +15,7 @@
import {AfterViewInit, Component, HostListener, Input, OnInit, ViewChild} from '@angular/core';
import {Location} from '@angular/common';
import {ActivatedRoute, Router} from '@angular/router';
import {AnimationController, IonRouterOutlet} from '@ionic/angular';
import {AnimationController, IonRouterOutlet} from '@ionic/angular/standalone';
import {SharedAxisChoreographer} from '../../../animation/animation-choreographer';
import {materialSharedAxisX} from '../../../animation/material-motion';
import {ScheduleResponsiveBreakpoint} from './schema/schema';

View File

@@ -26,7 +26,7 @@ ion-header {
}
}
ion-segment-button[aria-selected='true'] ion-icon ::ng-deep stapps-icon {
ion-segment-button.segment-button-checked ion-icon {
--fill: 1;
}

View File

@@ -21,7 +21,7 @@ import {SCISO8601Date, SCUuid} from '@openstapps/core';
import {ScheduleEvent, ScheduleResponsiveBreakpoint} from './schema/schema';
import {CalendarService} from '../../calendar/calendar.service';
import {CalendarComponent} from './components/calendar.component';
import {IonContent, IonDatetime} from '@ionic/angular';
import {IonContent, IonDatetime} from '@ionic/angular/standalone';
import {SwiperComponent} from 'swiper/angular';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

View File

@@ -16,7 +16,6 @@ import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {ScheduleCardComponent} from './page/grid/schedule-card.component';
@@ -35,8 +34,34 @@ import {ScheduleDayComponent} from './page/grid/schedule-day.component';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {InfiniteSwiperComponent} from './page/grid/infinite-swiper.component';
import {CalendarComponent} from './page/components/calendar.component';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {ChooseEventsPageComponent} from './page/choose-events-page.component';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonContent,
IonDatetime,
IonFab,
IonFabButton,
IonHeader,
IonItem,
IonItemGroup,
IonLabel,
IonList,
IonNote,
IonPopover,
IonRouterLink,
IonSegment,
IonSegmentButton,
IonText,
IonTitle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const settingsRoutes: Routes = [
{path: 'schedule', redirectTo: 'schedule/calendar/now'},
@@ -69,14 +94,37 @@ const settingsRoutes: Routes = [
CommonModule,
DataModule,
FormsModule,
IonicModule.forRoot(),
IonIconModule,
IonIconDirective,
MomentModule,
RouterModule.forChild(settingsRoutes),
SwiperModule,
TranslateModule.forChild(),
UtilModule,
ThingTranslateModule,
IonBackButton,
IonContent,
IonDatetime,
IonButton,
IonPopover,
IonText,
IonItem,
IonLabel,
IonFabButton,
IonList,
IonItemGroup,
IonFab,
IonSegment,
IonSegmentButton,
IonRouterLink,
IonToolbar,
IonButtons,
IonTitle,
IonNote,
IonCard,
IonCardContent,
IonHeader,
IonCardTitle,
IonCardHeader,
],
providers: [ScheduleProvider, DataProvider, DateFormatPipe],
})

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {AlertController} from '@ionic/angular';
import {AlertController} from '@ionic/angular/standalone';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {SCLanguageCode, SCSetting, SCSettingValue, SCSettingValues} from '@openstapps/core';
import {SettingsProvider} from '../settings.provider';

View File

@@ -15,7 +15,7 @@
import {Component, OnInit} from '@angular/core';
import {AddEventReviewModalComponent} from '../../calendar/add-event-review-modal.component';
import {ModalController} from '@ionic/angular';
import {ModalController} from '@ionic/angular/standalone';
import {ScheduleProvider} from '../../calendar/schedule.provider';
import {Directory, Encoding, Filesystem} from '@capacitor/filesystem';
import {Share} from '@capacitor/share';

View File

@@ -13,7 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {AlertController, ToastController} from '@ionic/angular';
import {AlertController, ToastController} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
import {SCSettingMeta} from '@openstapps/core';
import {SettingsCache, SettingsProvider} from '../settings.provider';

View File

@@ -16,7 +16,6 @@ import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
@@ -32,7 +31,30 @@ import {CalendarService} from '../calendar/calendar.service';
import {CalendarModule} from '../calendar/calendar.module';
import {BackgroundModule} from '../background/background.module';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {
IonBackButton,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonHeader,
IonInput,
IonItem,
IonItemDivider,
IonItemGroup,
IonLabel,
IonList,
IonNote,
IonRouterLink,
IonSelect,
IonSelectOption,
IonTitle,
IonToggle,
IonToolbar,
} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';
const settingsRoutes: Routes = [{path: 'settings', component: SettingsPageComponent}];
@@ -51,13 +73,33 @@ const settingsRoutes: Routes = [{path: 'settings', component: SettingsPageCompon
CommonModule,
FormsModule,
CalendarModule,
IonIconModule,
IonIconDirective,
BackgroundModule,
IonicModule.forRoot(),
TranslateModule.forChild(),
ThingTranslateModule.forChild(),
RouterModule.forChild(settingsRoutes),
UtilModule,
IonRouterLink,
IonBackButton,
IonButton,
IonList,
IonTitle,
IonButtons,
IonToolbar,
IonHeader,
IonLabel,
IonItem,
IonItemDivider,
IonItemGroup,
IonToggle,
IonCard,
IonCardContent,
IonCardSubtitle,
IonCardHeader,
IonSelect,
IonSelectOption,
IonInput,
IonNote,
],
providers: [ScheduleSyncService, SettingsProvider, CalendarService, ScheduleProvider, ThingTranslatePipe],
})

View File

@@ -29,16 +29,16 @@ import {
import {ThingTranslateDefaultParser, ThingTranslateParser} from './thing-translate.parser';
import {ThingTranslatePipe} from './thing-translate.pipe';
import {ThingTranslateService} from './thing-translate.service';
import {IonIconModule} from '../util/ion-icon/ion-icon.module';
import {TranslateSimplePipe} from './translate-simple.pipe';
import {PropertyNameTranslatePipe} from './property-name-translate.pipe';
import {IonIconDirective} from '../util/ion-icon/ion-icon.directive';
export interface ThingTranslateModuleConfig {
parser?: Provider;
}
@NgModule({
imports: [IonIconModule],
imports: [IonIconDirective],
declarations: [
ArrayJoinPipe,
DurationLocalizedPipe,
@@ -56,7 +56,6 @@ export interface ThingTranslateModuleConfig {
IsNumericPipe,
],
exports: [
IonIconModule,
ArrayJoinPipe,
DurationLocalizedPipe,
NumberLocalizedPipe,

View File

@@ -12,7 +12,7 @@
* 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 {Platform} from '@ionic/angular';
import {Platform} from '@ionic/angular/standalone';
import {Browser as BrowserPlugin} from '@capacitor/browser';
export abstract class SimpleBrowser {

View File

@@ -21,7 +21,7 @@ import {
IonModal,
IonRouterOutlet,
ModalController,
} from '@ionic/angular';
} from '@ionic/angular/standalone';
import {pendingChangesActionSheet, PendingChangesRole} from './pending-changes-action-sheet';
import {TranslatePipe} from '@ngx-translate/core';

View File

@@ -1,46 +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 {ChangeDetectionStrategy, Component, HostBinding, Input} from '@angular/core';
@Component({
selector: 'stapps-icon',
templateUrl: 'icon.html',
styleUrls: ['icon.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class IconComponent {
@HostBinding('style.--size')
@Input()
size?: number;
@HostBinding('style.--weight')
@Input()
weight?: number;
@HostBinding('style.--grade')
@Input()
grade?: number;
@HostBinding('style.--fill')
@Input()
fill?: number;
@HostBinding('innerHtml')
@Input()
name: string;
@HostBinding('class.material-symbols-rounded') hostClass = true;
}

View File

@@ -1,15 +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/>.
-->
<ng-content></ng-content>

View File

@@ -1,31 +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/>.
*/
:host {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
font-size: inherit;
font-variation-settings:
'wght' var(--weight),
'GRAD' var(--grade),
'FILL' var(--fill);
transition: all 0.2s ease-in-out;
}

View File

@@ -1,68 +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 {
DestroyRef,
Directive,
ElementRef,
Host,
inject,
OnInit,
Optional,
Self,
ViewContainerRef,
} from '@angular/core';
import {SCIcon} from './icon';
import {IconReplacer} from './replace-util';
import {TranslateService} from '@ngx-translate/core';
import {IonBackButton} from '@ionic/angular';
import {TitleCasePipe} from '@angular/common';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
@Directive({
selector: 'ion-back-button',
})
export class IonBackButtonDirective extends IconReplacer implements OnInit {
destroy$ = inject(DestroyRef);
constructor(
element: ElementRef,
viewContainerRef: ViewContainerRef,
@Host() @Self() @Optional() private ionBackButton: IonBackButton,
private translateService: TranslateService,
private titleCasePipe: TitleCasePipe,
) {
super(element, viewContainerRef, 'shadow');
}
replace() {
this.replaceIcon(this.host.querySelector('.button-inner'), {
md: SCIcon.arrow_back,
ios: SCIcon.arrow_back_ios,
size: 24,
});
}
async ngOnInit() {
await super.ngOnInit();
if (document.querySelector('ion-app[mode=ios]')) {
this.translateService
.stream('back')
.pipe(takeUntilDestroyed(this.destroy$))
.subscribe((value: string) => {
this.ionBackButton.text = this.titleCasePipe.transform(value);
});
}
}
}

View File

@@ -1,46 +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 {Directive, ElementRef, ViewContainerRef} from '@angular/core';
import {SCIcon} from './icon';
import {IconReplacer} from './replace-util';
@Directive({
selector: 'ion-breadcrumb',
})
export class IonBreadcrumbDirective extends IconReplacer {
constructor(element: ElementRef, viewContainerRef: ViewContainerRef) {
super(element, viewContainerRef, 'shadow');
}
replace() {
this.replaceIcon(
this.host.querySelector('span[part="separator"]'),
{
name: SCIcon.arrow_forward_ios,
size: 16,
style: `color: var(--ion-color-tint);`,
},
'-separator',
);
this.replaceIcon(
this.host.querySelector('button[part="collapsed-indicator"]'),
{
name: SCIcon.more_horiz,
size: 24,
},
'-collapsed',
);
}
}

View File

@@ -0,0 +1,161 @@
import {MaterialSymbol} from 'material-symbols';
import {SCIcon} from './icon';
import {
arrowBackOutline,
caretDownSharp,
chevronBackOutline,
chevronExpand,
chevronForwardOutline,
close,
closeCircle,
closeSharp,
ellipsisHorizontal,
menu,
menuSharp,
searchOutline,
searchSharp,
} from 'ionicons/icons';
const styles = new CSSStyleSheet();
styles.replaceSync(/* css */ `
:host {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1em;
height: 1em;
font-size: inherit;
font-variation-settings: 'wght' var(--weight, 400), 'GRAD' var(--grade, 1), 'FILL' var(--fill, 0);
transition: font-variation-settings 0.2s ease-in-out;
direction: ltr;
font-family: 'Material Symbols Rounded';
font-feature-settings: 'liga';
font-style: normal;
line-height: 1;
text-transform: none;
text-rendering: optimizelegibility;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
`);
export class IonIconCustomElement extends HTMLElement {
static observedAttributes = ['name', 'size', 'color', 'weight', 'grade', 'fill'];
set name(value: MaterialSymbol) {
this.shadowRoot!.textContent =
document.querySelector('ion-app.ios') && iosAlias.has(value) ? iosAlias.get(value)! : value;
}
set icon(value: string) {
if (iconMap.has(value)) {
this.name = iconMap.get(value)!;
} else {
this.style.setProperty('color', 'red');
// @ts-expect-error not assignable
this.name = '??';
console.error(
`The icon "${value}" is missing from the icon map (did Ionic change something?)`,
'\n\n',
new Error('...')!.stack,
);
}
}
set size(value: number | string | 'small' | 'large') {
switch (value) {
case 'small': {
this.style.setProperty('font-size', '1.125rem');
break;
}
case 'large': {
this.style.setProperty('font-size', '2rem');
break;
}
default: {
this.style.setProperty('font-size', Number.isNaN(Number(value)) ? value.toString() : `${value}px`);
}
}
}
set color(
value:
| 'primary'
| 'secondary'
| 'tertiary'
| 'success'
| 'warning'
| 'danger'
| 'light'
| 'medium'
| 'dark',
) {
this.style.setProperty('color', `var(--ion-color-${value}`);
}
set fill(value: boolean | undefined) {
if (value === undefined) {
this.style.removeProperty('--fill');
} else {
this.style.setProperty('--fill', Boolean(value) ? '1' : '0');
}
}
set weight(value: number | undefined) {
if (value === undefined) {
this.style.removeProperty('--weight');
} else {
this.style.setProperty('--weight', String(value));
}
}
set grade(value: number | undefined) {
if (value === undefined) {
this.style.removeProperty('--grade');
} else {
this.style.setProperty('--grade', String(value));
}
}
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
shadow.adoptedStyleSheets = [styles];
}
}
const iosAlias = new Map<MaterialSymbol, MaterialSymbol>([
[SCIcon.arrow_back, SCIcon.arrow_back_ios],
[SCIcon.arrow_forward, SCIcon.arrow_forward_ios],
[SCIcon.share, SCIcon.ios_share],
]);
/**
* Maps hardcoded icon SVGs to our icon names.
* Thanks, Ionic.
*/
const iconMap = new Map<string, MaterialSymbol>([
[arrowBackOutline, SCIcon.arrow_back],
[chevronBackOutline, SCIcon.arrow_back],
[chevronForwardOutline, SCIcon.arrow_forward],
[menu, SCIcon.menu],
[menuSharp, SCIcon.menu],
[searchOutline, SCIcon.search],
[searchSharp, SCIcon.search],
[chevronExpand, SCIcon.expand_more],
[caretDownSharp, SCIcon.expand_more],
[close, SCIcon.close],
[closeSharp, SCIcon.close],
[closeCircle, SCIcon.cancel],
[ellipsisHorizontal, SCIcon.more_horiz],
['chevron-down-outline', SCIcon.expand_more],
['arrow_back', SCIcon.arrow_back],
]);

View File

@@ -13,121 +13,37 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
ComponentRef,
Directive,
ElementRef,
Host,
Input,
OnChanges,
OnDestroy,
OnInit,
Optional,
Self,
ViewContainerRef,
} from '@angular/core';
import {IconComponent} from './icon.component';
import {IonIcon} from '@ionic/angular';
import {MaterialSymbol} from 'material-symbols';
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {};
const noopProperty = {
set: noop,
get: noop,
};
import {Directive, ElementRef, Input} from '@angular/core';
import {IonIconCustomElement} from './ion-icon-custom-component';
@Directive({
selector: 'ion-icon',
standalone: true,
})
export class IonIconDirective implements OnInit, OnDestroy, OnChanges {
@Input() name: MaterialSymbol;
@Input() md: string;
@Input() ios: string;
@Input() fill: boolean;
@Input() weight: number;
@Input() size: number | 'small' | 'large';
@Input() grade: number;
@Input() style: string;
private mutationObserver: MutationObserver;
iconComponent?: ComponentRef<IconComponent>;
private get mode(): 'md' | 'ios' {
return document.querySelector(':root')?.getAttribute('mode') as 'md' | 'ios';
export class IonIconDirective {
@Input({required: true}) set name(value: IonIconCustomElement['name']) {
this.elementRef.nativeElement.name = value;
}
constructor(
private element: ElementRef,
private viewContainerRef: ViewContainerRef,
@Host() @Self() @Optional() private ionIcon: IonIcon,
) {}
ngOnInit() {
this.iconComponent = this.viewContainerRef.createComponent(IconComponent, {});
this.element.nativeElement.insertBefore(
this.iconComponent.location.nativeElement,
this.element.nativeElement.firstChild,
);
this.mutationObserver = new MutationObserver(() => {
const inner = this.element.nativeElement.shadowRoot.querySelector('.icon-inner');
if (!inner) return;
inner.insertBefore(document.createElement('slot'), inner.firstChild);
});
this.mutationObserver.observe(this.element.nativeElement.shadowRoot, {
childList: true,
});
this.ngOnChanges();
// this will effectively completely disable the ion-icon component
for (const name of ['src', 'name', 'icon', 'md', 'ios']) {
this.disableProperty(name);
}
@Input() set size(value: IonIconCustomElement['size']) {
this.elementRef.nativeElement.size = value;
}
ngOnDestroy() {
this.mutationObserver.disconnect();
@Input() set color(value: IonIconCustomElement['color']) {
this.elementRef.nativeElement.color = value;
}
ngOnChanges() {
if (!this.iconComponent) return;
this.iconComponent.setInput('fill', this.fill === true ? 1 : this.fill === false ? 0 : this.fill);
this.iconComponent.setInput('weight', this.weight);
this.iconComponent.setInput('grade', this.grade);
if (this.mode === 'ios') {
this.iconComponent.setInput('name', this.ios || this.name);
} else {
this.iconComponent.setInput('name', this.md || this.name);
}
if (this.size) {
const size = this.size === 'small' ? 16 : this.size === 'large' ? 24 : this.size;
this.element.nativeElement.style.fontSize = `${size}px`;
}
if (this.style) {
this.element.nativeElement.style.cssText += this.style;
}
@Input() set fill(value: IonIconCustomElement['fill']) {
this.elementRef.nativeElement.fill = value;
}
disableProperty(name: string) {
Object.defineProperty(
Object.getPrototypeOf((this.ionIcon as unknown as {el: HTMLElement}).el),
name,
noopProperty,
);
@Input() set weight(value: IonIconCustomElement['weight']) {
this.elementRef.nativeElement.weight = value;
}
@Input() set grade(value: IonIconCustomElement['grade']) {
this.elementRef.nativeElement.grade = value;
}
constructor(private elementRef: ElementRef<IonIconCustomElement>) {}
}

View File

@@ -1,45 +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 {NgModule} from '@angular/core';
import {IconComponent} from './icon.component';
import {IonIconDirective} from './ion-icon.directive';
import {IonBackButtonDirective} from './ion-back-button.directive';
import {IonSearchbarDirective} from './ion-searchbar.directive';
import {IonBreadcrumbDirective} from './ion-breadcrumb.directive';
import {IonReorderDirective} from './ion-reorder.directive';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import {CommonModule, TitleCasePipe} from '@angular/common';
@NgModule({
imports: [TranslateModule, CommonModule],
declarations: [
IconComponent,
IonIconDirective,
IonBackButtonDirective,
IonSearchbarDirective,
IonBreadcrumbDirective,
IonReorderDirective,
],
exports: [
IonIconDirective,
IonReorderDirective,
IonBackButtonDirective,
IonSearchbarDirective,
IonBreadcrumbDirective,
],
providers: [TranslateService, TitleCasePipe],
})
export class IonIconModule {}

Some files were not shown because too many files have changed in this diff Show More