MOBILE-4459 storybook: Create storybook for new sites-list component
parent
2244864c07
commit
a0f81719f7
|
@ -0,0 +1,32 @@
|
|||
// (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 { CoreSiteFixture } from '@/storybook/stubs/classes/site';
|
||||
|
||||
export const companyLisaSite: CoreSiteFixture = {
|
||||
id: 'companylisasite',
|
||||
info: {
|
||||
version: '2022041900',
|
||||
sitename: 'Company',
|
||||
username: 'lisa',
|
||||
firstname: 'Lisa',
|
||||
lastname: 'Díaz',
|
||||
fullname: 'Lisa Díaz',
|
||||
lang: 'en',
|
||||
userid: 1,
|
||||
siteurl: 'https://company.example.edu',
|
||||
userpictureurl: 'https://i.pravatar.cc/300?user=companylisa',
|
||||
functions: [],
|
||||
},
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
{"id":"123456","info":{"version":"2022041900","sitename":"School","username":"barbara","firstname":"Barbara","lastname":"Gardner","fullname":"Barbara Gardner","lang":"en","userid":1,"siteurl":"https://campus.example.edu","userpictureurl":"","functions":[]}}
|
|
@ -0,0 +1,32 @@
|
|||
// (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 { CoreSiteFixture } from '@/storybook/stubs/classes/site';
|
||||
|
||||
export const schoolBarbaraSite: CoreSiteFixture = {
|
||||
id: 'schoolbarbarasite',
|
||||
info: {
|
||||
version: '2022041900',
|
||||
sitename: 'School',
|
||||
username: 'barbara',
|
||||
firstname: 'Barbara',
|
||||
lastname: 'Gardner',
|
||||
fullname: 'Barbara Gardner',
|
||||
lang: 'en',
|
||||
userid: 1,
|
||||
siteurl: 'https://campus.example.edu',
|
||||
userpictureurl: 'https://i.pravatar.cc/300?user=schoolbarbara',
|
||||
functions: [],
|
||||
},
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
// (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 { CoreSiteFixture } from '@/storybook/stubs/classes/site';
|
||||
|
||||
export const schoolJefferySite: CoreSiteFixture = {
|
||||
id: 'schooljefferysite',
|
||||
info: {
|
||||
version: '2022041900',
|
||||
sitename: 'School',
|
||||
username: 'jeffery',
|
||||
firstname: 'Jeffery',
|
||||
lastname: 'Sanders',
|
||||
fullname: 'Jeffery Sanders',
|
||||
lang: 'en',
|
||||
userid: 2,
|
||||
siteurl: 'https://campus.example.edu',
|
||||
userpictureurl: 'https://i.pravatar.cc/300?user=schooljeffery',
|
||||
functions: [],
|
||||
},
|
||||
};
|
|
@ -21,6 +21,8 @@ import { CoreComponentsModule } from '@components/components.module';
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { CoreCourseImageCardsPageComponent } from '@components/stories/components/course-image-cards-page/course-image-cards-page';
|
||||
import { CoreCourseImageListPageComponent } from '@components/stories/components/course-image-list-page/course-image-list-page';
|
||||
import { CoreSitesListWrapperComponent } from './sites-list-wrapper/sites-list-wrapper';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -28,10 +30,12 @@ import { CoreCourseImageListPageComponent } from '@components/stories/components
|
|||
CoreCourseImageListPageComponent,
|
||||
CoreEmptyBoxPageComponent,
|
||||
CoreEmptyBoxWrapperComponent,
|
||||
CoreSitesListWrapperComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
StorybookModule,
|
||||
CoreDirectivesModule,
|
||||
CoreComponentsModule,
|
||||
CoreSearchComponentsModule,
|
||||
],
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<ion-app>
|
||||
<ion-content class="limited-width">
|
||||
<core-sites-list *ngIf="accountsList" [accountsList]="accountsList" [sitesClickable]="sitesClickable"
|
||||
[currentSiteClickable]="currentSiteClickable" (onSiteClicked)="siteClicked($event)">
|
||||
|
||||
<ng-template *ngIf="extraText !== 'none'" #siteLabel let-site="site">
|
||||
<p *ngIf="extraText === 'text'">Extra text for user {{ site.fullname }}</p>
|
||||
<ion-badge *ngIf="extraText === 'badge'" color="light">{{ site.badge }} MB</ion-badge>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #siteItem let-site="site">
|
||||
<ion-button *ngIf="extraDetails === 'delete-button'" fill="clear" color="danger" slot="end">
|
||||
<ion-icon name="fas-trash" slot="icon-only"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-badge *ngIf="extraDetails === 'badge'" slot="end">
|
||||
<span>{{site.badge}}</span>
|
||||
</ion-badge>
|
||||
</ng-template>
|
||||
|
||||
</core-sites-list>
|
||||
</ion-content>
|
||||
</ion-app>
|
|
@ -0,0 +1,60 @@
|
|||
// (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, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { CoreAccountsList, CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreSiteBasicInfo } from '@services/sites';
|
||||
|
||||
@Component({
|
||||
selector: 'core-sites-list-wrapper',
|
||||
templateUrl: 'sites-list-wrapper.html',
|
||||
})
|
||||
export class CoreSitesListWrapperComponent implements OnInit, OnChanges {
|
||||
|
||||
@Input() sitesClickable = false;
|
||||
@Input() currentSiteClickableSelect = 'undefined';
|
||||
@Input() extraText: 'text' | 'badge' | 'none' = 'none';
|
||||
@Input() extraDetails: 'delete-button' | 'badge' | 'none' = 'none';
|
||||
|
||||
accountsList?: CoreAccountsList;
|
||||
currentSiteClickable?: boolean;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async ngOnChanges(changes: SimpleChanges): Promise<void> {
|
||||
if (changes.currentSiteClickableSelect) {
|
||||
this.currentSiteClickable = this.currentSiteClickableSelect === 'undefined' ?
|
||||
undefined :
|
||||
this.currentSiteClickableSelect === 'true';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Site clicked.
|
||||
*
|
||||
* @param site Site.
|
||||
*/
|
||||
siteClicked(site: CoreSiteBasicInfo): void {
|
||||
alert(`clicked on ${site.id} - ${site.fullname}`);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// (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 { Meta, moduleMetadata } from '@storybook/angular';
|
||||
|
||||
import { story } from '@/storybook/utils/helpers';
|
||||
import { CoreSitesListComponent } from '@components/sites-list/sites-list';
|
||||
import { CoreSitesListWrapperComponent } from './components/sites-list-wrapper/sites-list-wrapper';
|
||||
import { CoreComponentsStorybookModule } from './components/components.module';
|
||||
|
||||
interface Args {
|
||||
sitesClickable: boolean;
|
||||
currentSiteClickable: 'true' | 'false' | 'undefined';
|
||||
extraText: 'text' | 'badge' | 'none';
|
||||
extraDetails: 'delete-button' | 'badge' | 'none';
|
||||
}
|
||||
|
||||
export default <Meta<Args>> {
|
||||
title: 'Core/Sites List',
|
||||
component: CoreSitesListComponent,
|
||||
decorators: [
|
||||
moduleMetadata({ imports: [CoreComponentsStorybookModule] }),
|
||||
],
|
||||
argTypes: {
|
||||
sitesClickable: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
currentSiteClickable: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['true', 'false', 'undefined'],
|
||||
},
|
||||
},
|
||||
extraText: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['text', 'badge', 'none'],
|
||||
},
|
||||
},
|
||||
extraDetails: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['delete-button', 'badge', 'none'],
|
||||
},
|
||||
},
|
||||
},
|
||||
args: {
|
||||
sitesClickable: false,
|
||||
currentSiteClickable: 'undefined',
|
||||
extraText: 'none',
|
||||
extraDetails: 'none',
|
||||
},
|
||||
};
|
||||
|
||||
const Template = story<Args>(({ sitesClickable, currentSiteClickable, extraText, extraDetails }) => ({
|
||||
component: CoreSitesListWrapperComponent,
|
||||
props: {
|
||||
sitesClickable,
|
||||
currentSiteClickableSelect: currentSiteClickable,
|
||||
extraText,
|
||||
extraDetails,
|
||||
},
|
||||
}));
|
||||
|
||||
export const Primary = story<Args>(Template);
|
|
@ -50,7 +50,7 @@ export class CoreLoginSitesModalComponent implements OnInit {
|
|||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList(this.currentSiteId);
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList();
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1301,10 +1301,9 @@ export class CoreLoginHelperProvider {
|
|||
/**
|
||||
* Get the accounts list classified per site.
|
||||
*
|
||||
* @param currentSiteId If loggedin, current Site Id.
|
||||
* @returns Promise resolved with account list.
|
||||
*/
|
||||
async getAccountsList(currentSiteId?: string): Promise<CoreAccountsList> {
|
||||
async getAccountsList(): Promise<CoreAccountsList> {
|
||||
const sites = await CoreUtils.ignoreErrors(CoreSites.getSortedSites(), [] as CoreSiteBasicInfo[]);
|
||||
|
||||
const accountsList: CoreAccountsList = {
|
||||
|
@ -1312,14 +1311,11 @@ export class CoreLoginHelperProvider {
|
|||
otherSites: [],
|
||||
count: sites.length,
|
||||
};
|
||||
|
||||
const currentSiteId = CoreSites.getCurrentSiteId();
|
||||
let siteUrl = '';
|
||||
|
||||
if (currentSiteId) {
|
||||
const index = sites.findIndex((site) => site.id == currentSiteId);
|
||||
|
||||
accountsList.currentSite = sites.splice(index, 1)[0];
|
||||
siteUrl = accountsList.currentSite.siteUrlWithoutProtocol;
|
||||
siteUrl = sites.find((site) => site.id == currentSiteId)?.siteUrlWithoutProtocol ?? '';
|
||||
}
|
||||
|
||||
const otherSites: Record<string, CoreSiteBasicInfo[]> = {};
|
||||
|
@ -1328,7 +1324,9 @@ export class CoreLoginHelperProvider {
|
|||
await Promise.all(sites.map(async (site) => {
|
||||
site.badge = await CoreUtils.ignoreErrors(CorePushNotifications.getSiteCounter(site.id)) || 0;
|
||||
|
||||
if (site.siteUrlWithoutProtocol == siteUrl) {
|
||||
if (site.id === currentSiteId) {
|
||||
accountsList.currentSite = site;
|
||||
} else if (site.siteUrlWithoutProtocol == siteUrl) {
|
||||
accountsList.sameSite.push(site);
|
||||
} else {
|
||||
if (!otherSites[site.siteUrlWithoutProtocol]) {
|
||||
|
|
|
@ -104,10 +104,8 @@ export class CoreSettingsSynchronizationPage implements OnInit, OnDestroy {
|
|||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
const currentSiteId = CoreSites.getCurrentSiteId();
|
||||
|
||||
try {
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList(currentSiteId);
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList();
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import { CoreSharedFilesHelper } from '@features/sharedfiles/services/sharedfile
|
|||
import { FileEntry } from '@ionic-native/file/ngx';
|
||||
import { CoreFile } from '@services/file';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
|
||||
import { CoreSiteBasicInfo } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
||||
/**
|
||||
|
@ -94,7 +94,7 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
|
|||
* @returns Promise resolved when done.
|
||||
*/
|
||||
protected async loadSites(): Promise<void> {
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList(CoreSites.getCurrentSiteId());
|
||||
this.accountsList = await CoreLoginHelper.getAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1300,7 +1300,19 @@ export class CoreSitesProvider {
|
|||
async getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> {
|
||||
const sites = await this.sitesTable.getMany();
|
||||
|
||||
return this.siteDBRecordsToBasicInfo(sites, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert sites DB records to site basic info.
|
||||
*
|
||||
* @param sites DB records.
|
||||
* @param ids IDs of sites to return, undefined to return them all.
|
||||
* @returns Sites basic info.
|
||||
*/
|
||||
protected siteDBRecordsToBasicInfo(sites: SiteDBEntry[], ids?: string[]): CoreSiteBasicInfo[] {
|
||||
const formattedSites: CoreSiteBasicInfo[] = [];
|
||||
|
||||
sites.forEach((site) => {
|
||||
if (!ids || ids.indexOf(site.id) > -1) {
|
||||
const isDemoModeSite = CoreLoginHelper.isDemoModeSite(site.siteUrl);
|
||||
|
|
|
@ -28,6 +28,8 @@ import { CoreFilepoolProviderStub } from '@/storybook/stubs/services/filepool';
|
|||
import { CoreFilepoolProvider } from '@services/filepool';
|
||||
import { HttpClientStub } from '@/storybook/stubs/services/http';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
|
||||
import { CorePushNotificationsProviderStub } from './stubs/services/pushnotifications';
|
||||
|
||||
// For translate loader. AoT requires an exported function for factories.
|
||||
export class StaticTranslateLoader extends TranslateLoader {
|
||||
|
@ -56,6 +58,7 @@ export class StaticTranslateLoader extends TranslateLoader {
|
|||
{ provide: CoreSitesProvider, useClass: CoreSitesProviderStub },
|
||||
{ provide: CoreDbProvider, useClass: CoreDbProviderStub },
|
||||
{ provide: CoreFilepoolProvider, useClass: CoreFilepoolProviderStub },
|
||||
{ provide: CorePushNotificationsProvider, useClass: CorePushNotificationsProviderStub },
|
||||
{ provide: HttpClient, useClass: HttpClientStub },
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// (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 { CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
* Sites provider stub.
|
||||
*/
|
||||
export class CorePushNotificationsProviderStub extends CorePushNotificationsProvider {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async getSiteCounter(): Promise<number> {
|
||||
return Math.round(Math.random() * 100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CorePushNotificationsStub = makeSingleton<CorePushNotificationsProviderStub>(CorePushNotificationsProvider);
|
|
@ -12,9 +12,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import school from '@/assets/storybook/sites/school.json';
|
||||
import { companyLisaSite } from '@/assets/storybook/sites/companylisa';
|
||||
import { schoolBarbaraSite } from '@/assets/storybook/sites/schoolbarbara';
|
||||
import { schoolJefferySite } from '@/assets/storybook/sites/schooljeffery';
|
||||
import { CoreSiteFixture, CoreSiteStub } from '@/storybook/stubs/classes/site';
|
||||
import { CoreSitesProvider } from '@services/sites';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreSite } from '@classes/site';
|
||||
import { SiteDBEntry } from '@services/database/sites';
|
||||
import { CoreSiteBasicInfo, CoreSitesProvider } from '@services/sites';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
|
@ -22,17 +27,55 @@ import { makeSingleton } from '@singletons';
|
|||
*/
|
||||
export class CoreSitesProviderStub extends CoreSitesProvider {
|
||||
|
||||
protected static readonly SITES_FIXTURES = [schoolBarbaraSite, schoolJefferySite, companyLisaSite];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getRequiredCurrentSite!: () => CoreSiteStub;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> {
|
||||
const sites = CoreSitesProviderStub.SITES_FIXTURES.map(site => (<SiteDBEntry> {
|
||||
id: site.id,
|
||||
siteUrl: site.info.siteurl,
|
||||
info: JSON.stringify(site.info),
|
||||
token: '',
|
||||
privateToken: '',
|
||||
loggedOut: 0,
|
||||
}));
|
||||
|
||||
return this.siteDBRecordsToBasicInfo(sites, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async getSite(siteId?: string): Promise<CoreSite> {
|
||||
if (!siteId) {
|
||||
if (this.currentSite) {
|
||||
return this.currentSite;
|
||||
}
|
||||
|
||||
throw new CoreError('No current site found.');
|
||||
}
|
||||
|
||||
const siteFixture = CoreSitesProviderStub.SITES_FIXTURES.find(site => site.id === siteId);
|
||||
if (!siteFixture) {
|
||||
throw new CoreError('SiteId not found.');
|
||||
}
|
||||
|
||||
return new CoreSiteStub(siteFixture);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
stubCurrentSite(fixture?: CoreSiteFixture): CoreSiteStub {
|
||||
if (!this.currentSite) {
|
||||
this.currentSite = new CoreSiteStub(fixture ?? school);
|
||||
this.currentSite = new CoreSiteStub(fixture ?? schoolBarbaraSite);
|
||||
}
|
||||
|
||||
return this.getRequiredCurrentSite();
|
||||
|
|
Loading…
Reference in New Issue