Skip to content

Commit

Permalink
MOBILE-4459 storybook: Create storybook for new sites-list component
Browse files Browse the repository at this point in the history
  • Loading branch information
dpalou committed Nov 15, 2023
1 parent 7b4954d commit 27bc731
Show file tree
Hide file tree
Showing 16 changed files with 364 additions and 18 deletions.
32 changes: 32 additions & 0 deletions src/assets/storybook/sites/companylisa.ts
Original file line number Diff line number Diff line change
@@ -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 change: 0 additions & 1 deletion src/assets/storybook/sites/school.json

This file was deleted.

32 changes: 32 additions & 0 deletions src/assets/storybook/sites/schoolbarbara.ts
Original file line number Diff line number Diff line change
@@ -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: [],
},
};
32 changes: 32 additions & 0 deletions src/assets/storybook/sites/schooljeffery.ts
Original file line number Diff line number Diff line change
@@ -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: [],
},
};
4 changes: 4 additions & 0 deletions src/core/components/stories/components/components.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@ 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: [
CoreCourseImageCardsPageComponent,
CoreCourseImageListPageComponent,
CoreEmptyBoxPageComponent,
CoreEmptyBoxWrapperComponent,
CoreSitesListWrapperComponent,
],
imports: [
CommonModule,
StorybookModule,
CoreDirectivesModule,
CoreComponentsModule,
CoreSearchComponentsModule,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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}`);
}

}
78 changes: 78 additions & 0 deletions src/core/components/stories/site-list.stories.ts
Original file line number Diff line number Diff line change
@@ -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/Site 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);
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
14 changes: 6 additions & 8 deletions src/core/features/login/services/login-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1301,25 +1301,21 @@ 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 = {
sameSite: [],
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[]> = {};
Expand All @@ -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]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -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();
}

/**
Expand Down
12 changes: 12 additions & 0 deletions src/core/services/sites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 27bc731

Please sign in to comment.