MOBILE-4459 core: Create and use core-sites-list component
parent
d27d3ddec3
commit
a9bae5937c
|
@ -65,6 +65,7 @@ import { CoreGroupSelectorComponent } from './group-selector/group-selector';
|
|||
import { CoreRefreshButtonModalComponent } from './refresh-button-modal/refresh-button-modal';
|
||||
import { CoreSheetModalComponent } from '@components/sheet-modal/sheet-modal';
|
||||
import { CoreCourseImageComponent } from '@components/course-image/course-image';
|
||||
import { CoreSitesListComponent } from './sites-list/sites-list';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -112,6 +113,7 @@ import { CoreCourseImageComponent } from '@components/course-image/course-image'
|
|||
CoreSwipeNavigationTourComponent,
|
||||
CoreRefreshButtonModalComponent,
|
||||
CoreSheetModalComponent,
|
||||
CoreSitesListComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -166,6 +168,7 @@ import { CoreCourseImageComponent } from '@components/course-image/course-image'
|
|||
CoreSwipeNavigationTourComponent,
|
||||
CoreRefreshButtonModalComponent,
|
||||
CoreSheetModalComponent,
|
||||
CoreSitesListComponent,
|
||||
],
|
||||
})
|
||||
export class CoreComponentsModule {}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<ion-list class="core-sites-list" *ngIf="accountsList">
|
||||
<ion-card *ngIf="accountsList.currentSite">
|
||||
<ng-container *ngTemplateOutlet="siteCardHeader; context: {site: accountsList.currentSite, isCurrentSite: true}"></ng-container>
|
||||
|
||||
<ng-container *ngTemplateOutlet="siteItem; context: {site: accountsList.currentSite, isCurrentSite: true}"></ng-container>
|
||||
|
||||
<ng-container *ngFor="let site of accountsList.sameSite">
|
||||
<ng-container *ngTemplateOutlet="siteItem; context: {site: site, isCurrentSite: false}"></ng-container>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngFor="let sites of accountsList.otherSites">
|
||||
<ng-container *ngTemplateOutlet="siteCardHeader; context: {site: sites[0], isCurrentSite: false}"></ng-container>
|
||||
|
||||
<ng-container *ngFor="let site of sites">
|
||||
<ng-container *ngTemplateOutlet="siteItem; context: {site: site, isCurrentSite: false}"></ng-container>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<!-- Template to render the header of a site card. -->
|
||||
<ng-template #siteCardHeader let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
<ion-item-divider sticky="true" *ngIf="site" class="core-sites-list-sitename">
|
||||
<ion-label>
|
||||
<h2>
|
||||
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text>
|
||||
</h2>
|
||||
<p *ngIf="!site.isDemoModeSite">
|
||||
<a [href]="site.siteUrl" core-link [autoLogin]="isCurrentSite ? 'yes' : 'no'">
|
||||
{{ site.siteUrlWithoutProtocol }}
|
||||
</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
</ng-template>
|
||||
|
||||
<!-- Template to render a site item. -->
|
||||
<ng-template #siteItem let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
<ion-item [attr.button]="isSiteClickable(isCurrentSite) ? true : null" (click)="siteClicked($event, site, isCurrentSite)"
|
||||
[attr.detail]="isSiteClickable(isCurrentSite) ? 'true' : 'false'" [class.item-current]="isCurrentSite">
|
||||
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
<ng-container *ngIf="siteLabelTemplate" [ngTemplateOutlet]="siteLabelTemplate"
|
||||
[ngTemplateOutletContext]="{site: site, isCurrentSite: isCurrentSite}">
|
||||
</ng-container>
|
||||
</ion-label>
|
||||
|
||||
<ng-container *ngIf="siteItemTemplate" [ngTemplateOutlet]="siteItemTemplate"
|
||||
[ngTemplateOutletContext]="{site: site, isCurrentSite: isCurrentSite}">
|
||||
</ng-container>
|
||||
</ion-item>
|
||||
</ng-template>
|
|
@ -1,5 +1,5 @@
|
|||
ion-list.core-sitelist {
|
||||
.core-sitelist-sitename {
|
||||
ion-list.core-sites-list {
|
||||
.core-sites-list-sitename {
|
||||
ion-label {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
|
@ -0,0 +1,80 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, ContentChild, Input, Output, TemplateRef, EventEmitter } from '@angular/core';
|
||||
|
||||
import { CoreSiteBasicInfo } from '@services/sites';
|
||||
import { CoreAccountsList } from '@features/login/services/login-helper';
|
||||
|
||||
/**
|
||||
* Component to display a list of sites (accounts).
|
||||
*
|
||||
* By default this component will display the avatar and user fullname for each site, but it allows adding more information
|
||||
* in the item and in the label for each site, using #siteItem and #siteLabel ng-templates. These templates will receive the
|
||||
* site being rendered and whether it's the current site or not. Example:
|
||||
*
|
||||
* <core-sites-list [accountsList]="accountsList">
|
||||
* <ng-template #siteLabel let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
* <!-- Content to be placed in the label, after the user full name.
|
||||
* </ng-template>
|
||||
*
|
||||
* <ng-template #siteItem let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
* <!-- Content to be placed in the item.
|
||||
* </ng-template>
|
||||
* </core-sites-list>
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-sites-list',
|
||||
templateUrl: 'sites-list.html',
|
||||
styleUrls: ['sites-list.scss'],
|
||||
})
|
||||
export class CoreSitesListComponent<T extends CoreSiteBasicInfo> {
|
||||
|
||||
@Input() accountsList!: CoreAccountsList<T>;
|
||||
@Input() sitesClickable = false; // Whether the sites are clickable.
|
||||
@Input() currentSiteClickable?: boolean; // If set, specify a different clickable value for current site.
|
||||
@Output() onSiteClicked = new EventEmitter<T>();
|
||||
|
||||
@ContentChild('siteItem') siteItemTemplate?: TemplateRef<unknown>;
|
||||
@ContentChild('siteLabel') siteLabelTemplate?: TemplateRef<unknown>;
|
||||
|
||||
/**
|
||||
* Check whether a site is clickable.
|
||||
*
|
||||
* @param isCurrentSite Whether the site is current site.
|
||||
* @returns Whether it's clickable.
|
||||
*/
|
||||
isSiteClickable(isCurrentSite: boolean): boolean {
|
||||
return isCurrentSite ? this.currentSiteClickable ?? this.sitesClickable : this.sitesClickable;
|
||||
}
|
||||
|
||||
/**
|
||||
* A site was clicked.
|
||||
*
|
||||
* @param ev Event.
|
||||
* @param site Site clicked.
|
||||
* @param isCurrentSite Whether the site is current site.
|
||||
*/
|
||||
siteClicked(ev: Event, site: T, isCurrentSite: boolean): void {
|
||||
if (!this.isSiteClickable(isCurrentSite)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
this.onSiteClicked.emit(site);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,68 +20,12 @@
|
|||
</ion-header>
|
||||
<ion-content>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<ion-list class="core-sitelist">
|
||||
<ion-card *ngIf="accountsList.currentSite">
|
||||
<ion-item-divider sticky="true" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<h2>
|
||||
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
|
||||
[siteId]="accountsList.currentSite.id"></core-format-text>
|
||||
</h2>
|
||||
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
|
||||
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
|
||||
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
|
||||
</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<core-sites-list [accountsList]="accountsList" [sitesClickable]="true" [currentSiteClickable]="false"
|
||||
(onSiteClicked)="login($event)">
|
||||
<ng-template #siteItem let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
<ion-icon *ngIf="isCurrentSite" color="success" name="fas-check"></ion-icon>
|
||||
|
||||
<ion-item detail="false">
|
||||
<core-user-avatar [user]="accountsList.currentSite" slot="start" [linkProfile]="false"
|
||||
[siteId]="accountsList.currentSite.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{accountsList.currentSite.fullname}}</p>
|
||||
</ion-label>
|
||||
<ion-icon color="success" name="fas-check"></ion-icon>
|
||||
</ion-item>
|
||||
|
||||
<ng-container *ngTemplateOutlet="siteList; context: {sites: accountsList.sameSite}"></ng-container>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngFor="let sites of accountsList.otherSites">
|
||||
<ion-item-divider sticky="true" *ngIf="sites[0]" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<h2>
|
||||
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
|
||||
</h2>
|
||||
<p *ngIf="!sites[0].isDemoModeSite">
|
||||
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ng-container *ngTemplateOutlet="siteList; context: {sites: sites}"></ng-container>
|
||||
</ion-card>
|
||||
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
|
||||
<ion-fab-button (click)="add($event)" [attr.aria-label]="'core.login.add' | translate">
|
||||
<ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
|
||||
<span class="sr-only">{{ 'core.login.add' | translate }}</span>
|
||||
</ion-fab-button>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
|
||||
<!-- Template to render a list of sites. -->
|
||||
<ng-template #siteList let-sites="sites">
|
||||
<ion-item button *ngFor="let site of sites" (click)="login($event, site.id)" detail="true">
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
</ion-label>
|
||||
<ng-container *ngIf="!isCurrentSite">
|
||||
<ion-badge slot="end" *ngIf="!showDelete && site.badge" @coreShowHideAnimation>
|
||||
<span aria-hidden="true">{{site.badge}}</span>
|
||||
<span class="sr-only">{{ 'core.login.sitebadgedescription' | translate:{ count: site.badge }
|
||||
|
@ -91,5 +35,14 @@
|
|||
[attr.aria-label]="'core.login.removeaccount' | translate" [@coreSlideInOut]="'fromRight'">
|
||||
<ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</core-sites-list>
|
||||
</core-loading>
|
||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
|
||||
<ion-fab-button (click)="add($event)" [attr.aria-label]="'core.login.add' | translate">
|
||||
<ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
|
||||
<span class="sr-only">{{ 'core.login.add' | translate }}</span>
|
||||
</ion-fab-button>
|
||||
</ion-fab>
|
||||
</ion-content>
|
||||
|
|
|
@ -28,7 +28,6 @@ import { ModalController } from '@singletons';
|
|||
@Component({
|
||||
selector: 'core-login-sites',
|
||||
templateUrl: 'sites.html',
|
||||
styleUrls: ['../../sitelist.scss'],
|
||||
animations: [CoreAnimations.SLIDE_IN_OUT, CoreAnimations.SHOW_HIDE],
|
||||
})
|
||||
export class CoreLoginSitesComponent implements OnInit {
|
||||
|
@ -99,15 +98,14 @@ export class CoreLoginSitesComponent implements OnInit {
|
|||
/**
|
||||
* Login in a site.
|
||||
*
|
||||
* @param event Click event.
|
||||
* @param siteId The site ID.
|
||||
* @param site The site.
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async login(event: Event, siteId: string): Promise<void> {
|
||||
await this.close(event, true);
|
||||
async login(site: CoreSiteBasicInfo): Promise<void> {
|
||||
await this.close(undefined, true);
|
||||
|
||||
// This navigation will logout and navigate to the site home.
|
||||
await CoreNavigator.navigateToSiteHome({ preferCurrentTab: false , siteId });
|
||||
await CoreNavigator.navigateToSiteHome({ preferCurrentTab: false , siteId: site.id });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,9 +120,9 @@ export class CoreLoginSitesComponent implements OnInit {
|
|||
*
|
||||
* @param event Click event.
|
||||
*/
|
||||
async close(event: Event, closeAll = false): Promise<void> {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
async close(event?: Event, closeAll = false): Promise<void> {
|
||||
event?.preventDefault();
|
||||
event?.stopPropagation();
|
||||
|
||||
await ModalController.dismiss(closeAll);
|
||||
}
|
||||
|
|
|
@ -21,25 +21,8 @@
|
|||
</ion-header>
|
||||
<ion-content class="limited-width">
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<ion-list class="core-sitelist">
|
||||
<ion-card *ngFor="let sites of accountsList.otherSites">
|
||||
<ion-item-divider sticky="true" *ngIf="sites[0]" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<h2>
|
||||
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
|
||||
</h2>
|
||||
<p *ngIf="!sites[0].isDemoModeSite">
|
||||
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item button *ngFor="let site of sites" (click)="login($event, site.id)" detail="true">
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
</ion-label>
|
||||
<core-sites-list [accountsList]="accountsList" [sitesClickable]="true" (onSiteClicked)="login($event)">
|
||||
<ng-template #siteItem let-site="site" let-isCurrentSite="isCurrentSite">
|
||||
<ion-badge slot="end" *ngIf="!showDelete && site.badge" @coreShowHideAnimation>
|
||||
<span aria-hidden="true">{{site.badge}}</span>
|
||||
<span class="sr-only">{{ 'core.login.sitebadgedescription' | translate:{ count: site.badge }
|
||||
|
@ -49,9 +32,8 @@
|
|||
[attr.aria-label]="'core.login.removeaccount' | translate" [@coreSlideInOut]="'fromRight'">
|
||||
<ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
</ion-list>
|
||||
</ng-template>
|
||||
</core-sites-list>
|
||||
</core-loading>
|
||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
|
||||
<ion-fab-button (click)="add()" [attr.aria-label]="'core.login.add' | translate">
|
||||
|
|
|
@ -22,12 +22,11 @@ import { CoreFilter } from '@features/filter/services/filter';
|
|||
import { CoreAnimations } from '@components/animations';
|
||||
|
||||
/**
|
||||
* Page that displays a "splash screen" while the app is being initialized.
|
||||
* Page that displays the list of sites stored in the device.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'page-core-login-sites',
|
||||
templateUrl: 'sites.html',
|
||||
styleUrls: ['../../sitelist.scss'],
|
||||
animations: [CoreAnimations.SLIDE_IN_OUT, CoreAnimations.SHOW_HIDE],
|
||||
})
|
||||
export class CoreLoginSitesPage implements OnInit {
|
||||
|
@ -102,18 +101,14 @@ export class CoreLoginSitesPage implements OnInit {
|
|||
/**
|
||||
* Login in a site.
|
||||
*
|
||||
* @param event Click event.
|
||||
* @param siteId The site ID.
|
||||
* @param site The site.
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async login(event: Event, siteId: string): Promise<void> {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
async login(site: CoreSiteBasicInfo): Promise<void> {
|
||||
const modal = await CoreDomUtils.showModalLoading();
|
||||
|
||||
try {
|
||||
const loggedIn = await CoreSites.loadSite(siteId);
|
||||
const loggedIn = await CoreSites.loadSite(site.id);
|
||||
|
||||
if (loggedIn) {
|
||||
await CoreNavigator.navigateToSiteHome();
|
||||
|
|
|
@ -1541,10 +1541,10 @@ export const CoreLoginHelper = makeSingleton(CoreLoginHelperProvider);
|
|||
/**
|
||||
* Accounts list for selecting sites interfaces.
|
||||
*/
|
||||
export type CoreAccountsList = {
|
||||
currentSite?: CoreSiteBasicInfo; // If logged in, current site info.
|
||||
sameSite: CoreSiteBasicInfo[]; // If logged in, accounts info on the same site.
|
||||
otherSites: CoreSiteBasicInfo[][]; // Other accounts in other sites.
|
||||
export type CoreAccountsList<T extends CoreSiteBasicInfo = CoreSiteBasicInfo> = {
|
||||
currentSite?: T; // If logged in, current site info.
|
||||
sameSite: T[]; // If logged in, accounts info on the same site.
|
||||
otherSites: T[][]; // Other accounts in other sites.
|
||||
count: number; // Number of sites.
|
||||
};
|
||||
|
||||
|
|
|
@ -17,47 +17,21 @@
|
|||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<ion-list class="core-sitelist limited-width">
|
||||
<ion-card *ngIf="accountsList.currentSite">
|
||||
<ion-item-divider sticky="true" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
|
||||
[siteId]="accountsList.currentSite.id"></core-format-text>
|
||||
</p>
|
||||
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
|
||||
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
|
||||
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
|
||||
</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<ion-list class="limited-width">
|
||||
<core-sites-list [accountsList]="accountsList">
|
||||
<ng-template #siteLabel let-site="site">
|
||||
<ion-badge color="light" *ngIf="site.spaceUsage !== undefined">{{ site.spaceUsage | coreBytesToSize }}</ion-badge>
|
||||
</ng-template>
|
||||
|
||||
<ion-item class="item-current">
|
||||
<ng-container *ngTemplateOutlet="siteUsage; context: {site: accountsList.currentSite}"></ng-container>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngFor="let site of accountsList.sameSite">
|
||||
<ng-container *ngTemplateOutlet="siteUsage; context: {site: site}"></ng-container>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngFor="let sites of accountsList.otherSites">
|
||||
<ion-item-divider sticky="true" *ngIf="sites[0]" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
|
||||
</p>
|
||||
<p *ngIf="!sites[0].isDemoModeSite">
|
||||
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item *ngFor="let site of sites">
|
||||
<ng-container *ngTemplateOutlet="siteUsage; context: {site: site}"></ng-container>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<ng-template #siteItem let-site="site">
|
||||
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage(site)"
|
||||
[hidden]="site.spaceUsage <= 0 && !site.hasCacheEntries">
|
||||
<ion-icon name="fas-trash" slot="icon-only"
|
||||
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: site.siteName }">
|
||||
</ion-icon>
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
</core-sites-list>
|
||||
|
||||
<ion-item-divider>
|
||||
<ion-label>
|
||||
|
@ -70,19 +44,3 @@
|
|||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
|
||||
<!-- Template to render a site space usage. -->
|
||||
<ng-template #siteUsage let-site="site">
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label class="ion-text-wrap">
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
<ion-badge color="light" *ngIf="site.spaceUsage !== undefined">{{ site.spaceUsage | coreBytesToSize }}</ion-badge>
|
||||
</ion-label>
|
||||
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage(site)"
|
||||
[hidden]="site.spaceUsage <= 0 && !site.hasCacheEntries">
|
||||
<ion-icon name="fas-trash" slot="icon-only"
|
||||
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: site.siteName }">
|
||||
</ion-icon>
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
|
|
|
@ -20,6 +20,7 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||
|
||||
import { CoreSettingsHelper } from '../../services/settings-helper';
|
||||
import { CoreAccountsList } from '@features/login/services/login-helper';
|
||||
|
||||
/**
|
||||
* Page that displays the space usage settings.
|
||||
|
@ -33,9 +34,10 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
|
|||
loaded = false;
|
||||
totalSpaceUsage = 0;
|
||||
|
||||
accountsList: CoreAccountsListWithUsage = {
|
||||
accountsList: CoreAccountsList<CoreSiteBasicInfoWithUsage> = {
|
||||
sameSite: [],
|
||||
otherSites: [],
|
||||
count: 0,
|
||||
};
|
||||
|
||||
protected sitesObserver: CoreEventObserver;
|
||||
|
@ -128,6 +130,7 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
|
|||
});
|
||||
|
||||
this.accountsList.otherSites = CoreUtils.objectToArray(otherSites);
|
||||
this.accountsList.count = sites.length;
|
||||
|
||||
this.totalSpaceUsage = totalSize;
|
||||
}
|
||||
|
@ -192,12 +195,3 @@ interface CoreSiteBasicInfoWithUsage extends CoreSiteBasicInfo {
|
|||
hasCacheEntries: boolean; // If has cached entries that can be cleared.
|
||||
spaceUsage: number; // Space used in this site.
|
||||
}
|
||||
|
||||
/**
|
||||
* Accounts list for selecting sites interfaces.
|
||||
*/
|
||||
type CoreAccountsListWithUsage = {
|
||||
currentSite?: CoreSiteBasicInfoWithUsage; // If logged in, current site info.
|
||||
sameSite: CoreSiteBasicInfoWithUsage[]; // If logged in, accounts info on the same site.
|
||||
otherSites: CoreSiteBasicInfoWithUsage[][]; // Other accounts in other sites.
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</ion-header>
|
||||
<ion-content class="limited-width">
|
||||
<core-loading [hideUntil]="sitesLoaded">
|
||||
<ion-list class="core-sitelist limited-width">
|
||||
<ion-list class="limited-width">
|
||||
<ion-item-divider>
|
||||
<ion-label>
|
||||
<h2>{{ 'core.settings.syncsettings' | translate }}</h2>
|
||||
|
@ -51,65 +51,25 @@
|
|||
</ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-card *ngIf="accountsList.currentSite">
|
||||
<ion-item-divider sticky="true" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
|
||||
[siteId]="accountsList.currentSite.id"></core-format-text>
|
||||
</p>
|
||||
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
|
||||
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
|
||||
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
|
||||
</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<core-sites-list [accountsList]="accountsList">
|
||||
<ng-template #siteLabel let-site="site">
|
||||
<p class="text-danger" *ngIf="site.loggedOut">{{ 'core.settings.logintosync' | translate }}</p>
|
||||
</ng-template>
|
||||
|
||||
<ion-item class="item-current">
|
||||
<ng-container *ngTemplateOutlet="siteSync; context: {site: accountsList.currentSite}"></ng-container>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngFor="let site of accountsList.sameSite">
|
||||
<ng-container *ngTemplateOutlet="siteSync; context: {site: site}"></ng-container>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<ion-card *ngFor="let sites of accountsList.otherSites">
|
||||
<ion-item-divider sticky="true" *ngIf="sites[0]" class="core-sitelist-sitename">
|
||||
<ion-label>
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
|
||||
</p>
|
||||
<p *ngIf="!sites[0].isDemoModeSite">
|
||||
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item *ngFor="let site of sites">
|
||||
<ng-container *ngTemplateOutlet="siteSync; context: {site: site}"></ng-container>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<ng-template #siteItem let-site="site">
|
||||
<core-button-with-spinner [loading]="isSynchronizing(site.id)" slot="end" *ngIf="!site.loggedOut">
|
||||
<ion-button fill="clear" (click)="synchronize(site.id)"
|
||||
[attr.aria-label]="'core.settings.synchronizenow' | translate">
|
||||
<ion-icon name="fas-rotate" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</core-button-with-spinner>
|
||||
<ion-button fill="clear" (click)="login(site.id)" [attr.aria-label]="'core.login.login' | translate"
|
||||
*ngIf="site.loggedOut" slot="end">
|
||||
<ion-icon name="fas-right-to-bracket" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
</core-sites-list>
|
||||
</ng-container>
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
|
||||
<!-- Template to render a site to sync. -->
|
||||
<ng-template #siteSync let-site="site">
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
<p class="text-danger" *ngIf="site.loggedOut">{{ 'core.settings.logintosync' | translate }}</p>
|
||||
</ion-label>
|
||||
<core-button-with-spinner [loading]="isSynchronizing(site.id)" slot="end" *ngIf="!site.loggedOut">
|
||||
<ion-button fill="clear" (click)="synchronize(site.id)" [attr.aria-label]="'core.settings.synchronizenow' | translate">
|
||||
<ion-icon name="fas-rotate" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</core-button-with-spinner>
|
||||
<ion-button fill="clear" (click)="login(site.id)" [attr.aria-label]="'core.login.login' | translate" *ngIf="site.loggedOut" slot="end">
|
||||
<ion-icon name="fas-right-to-bracket" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</ng-template>
|
||||
|
|
|
@ -32,7 +32,6 @@ import { CoreNavigator } from '@services/navigator';
|
|||
@Component({
|
||||
selector: 'page-core-app-settings-synchronization',
|
||||
templateUrl: 'synchronization.html',
|
||||
styleUrls: ['../../../login/sitelist.scss'],
|
||||
})
|
||||
export class CoreSettingsSynchronizationPage implements OnInit, OnDestroy {
|
||||
|
||||
|
|
|
@ -17,17 +17,8 @@
|
|||
<p>{{fileName}}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item *ngFor="let site of sites" (click)="storeInSite(site.id)" detail="false" button>
|
||||
<core-user-avatar [user]="site" slot="start" [linkProfile]="false" [siteId]="site.id"></core-user-avatar>
|
||||
|
||||
<ion-label>
|
||||
<p class="item-heading">{{site.fullname}}</p>
|
||||
<p>
|
||||
<core-format-text clean="true" [text]="site.siteName" [siteId]="site.id"></core-format-text>
|
||||
</p>
|
||||
<p *ngIf="!site.isDemoModeSite">{{site.siteUrl}}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<core-sites-list [accountsList]="accountsList" [sitesClickable]="true" (onSiteClicked)="storeInSite($event)">
|
||||
</core-sites-list>
|
||||
</ion-list>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CoreAccountsList, CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreSharedFilesHelper } from '@features/sharedfiles/services/sharedfiles-helper';
|
||||
import { FileEntry } from '@ionic-native/file/ngx';
|
||||
import { CoreFile } from '@services/file';
|
||||
|
@ -30,8 +31,12 @@ import { CoreDomUtils } from '@services/utils/dom';
|
|||
export class CoreSharedFilesChooseSitePage implements OnInit {
|
||||
|
||||
fileName?: string;
|
||||
sites?: CoreSiteBasicInfo[];
|
||||
loaded = false;
|
||||
accountsList: CoreAccountsList = {
|
||||
sameSite: [],
|
||||
otherSites: [],
|
||||
count: 0,
|
||||
};
|
||||
|
||||
protected filePath?: string;
|
||||
protected fileEntry?: FileEntry;
|
||||
|
@ -89,15 +94,15 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
|
|||
* @returns Promise resolved when done.
|
||||
*/
|
||||
protected async loadSites(): Promise<void> {
|
||||
this.sites = await CoreSites.getSites();
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList(CoreSites.getCurrentSiteId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the file in a certain site.
|
||||
*
|
||||
* @param siteId Site ID.
|
||||
* @param site Site.
|
||||
*/
|
||||
async storeInSite(siteId: string): Promise<void> {
|
||||
async storeInSite(site: CoreSiteBasicInfo): Promise<void> {
|
||||
if (!this.fileEntry) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +110,7 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
|
|||
this.loaded = false;
|
||||
|
||||
try {
|
||||
await CoreSharedFilesHelper.storeSharedFileInSite(this.fileEntry, siteId, this.isInbox);
|
||||
await CoreSharedFilesHelper.storeSharedFileInSite(this.fileEntry, site.id, this.isInbox);
|
||||
|
||||
CoreNavigator.back();
|
||||
} finally {
|
||||
|
|
Loading…
Reference in New Issue