Skip to content

Commit

Permalink
feat(showcase): otter-picker (#995)
Browse files Browse the repository at this point in the history
  • Loading branch information
fpaul-1A authored Nov 6, 2023
2 parents 88a7f1b + 411baeb commit 0899d9d
Show file tree
Hide file tree
Showing 44 changed files with 398 additions and 85 deletions.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/astronotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/bonotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/c3potter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/colombotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/djokotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/hallowtter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/harry-otter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/jack-sparrowtter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/mandalotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/mariotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/neotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/pizzaiotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/ronaldotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/showcase/src/assets/mini-otters/sombrerotter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 20 additions & 3 deletions apps/showcase/src/components/showcase/sdk/sdk-pres.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgbHighlight, NgbPagination } from '@ng-bootstrap/ng-bootstrap';
import { O3rComponent } from '@o3r/core';
import { OtterPickerPresComponent } from '../../utilities';

@O3rComponent({ componentType: 'Component' })
@Component({
selector: 'o3r-sdk-pres',
standalone: true,
imports: [CommonModule, NgbHighlight, FormsModule, NgbPagination],
imports: [CommonModule, NgbHighlight, FormsModule, NgbPagination, OtterPickerPresComponent],
templateUrl: './sdk-pres.template.html',
styleUrls: ['./sdk-pres.style.scss'],
encapsulation: ViewEncapsulation.None,
Expand All @@ -24,6 +25,11 @@ export class SdkPresComponent {
*/
public petName = signal('');

/**
* File input used to create new pets
*/
public petImage = signal('');

/**
* Search term used to filter the list of pets
*/
Expand Down Expand Up @@ -83,6 +89,9 @@ export class SdkPresComponent {
this.filteredPets().slice((this.currentPage() - 1) * this.pageSize(), (this.currentPage()) * this.pageSize())
);

/** Base URL where the images can be fetched */
public baseUrl = location.href.split('/#', 1)[0];

constructor() {
void this.reload();
}
Expand All @@ -98,7 +107,7 @@ export class SdkPresComponent {
this.isLoading.set(true);
this.hasErrors.set(false);
return this.petStoreApi.findPetsByStatus({status: 'available'}).then((pets) => {
this.pets.set(pets.sort((a, b) => a.id && b.id && a.id - b.id || 0));
this.pets.set(pets.filter((p) => p.category?.name === 'otter').sort((a, b) => a.id && b.id && a.id - b.id || 0));
this.isLoading.set(false);
}).catch(() => {
this.isLoading.set(false);
Expand All @@ -116,13 +125,21 @@ export class SdkPresComponent {
category: {name: 'otter'},
tags: [{name: 'otter'}],
status: 'available',
photoUrls: []
photoUrls: this.petName() ? [this.petImage()] : []
};
this.isLoading.set(true);
await this.petStoreApi.addPet({
// eslint-disable-next-line @typescript-eslint/naming-convention
Pet: pet
});
if (pet.photoUrls.length) {
const filePath = `${this.baseUrl}${pet.photoUrls[0] as string}`;
const blob = await (await fetch(filePath)).blob();
await this.petStoreApi.uploadFile({
petId: pet.id!,
body: new File([blob], filePath, {type: blob.type})
});
}
await this.reload();
}

Expand Down
12 changes: 10 additions & 2 deletions apps/showcase/src/components/showcase/sdk/sdk-pres.style.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
o3r-sdk-pres {
.table-container {
min-height: 33rem;
.table-container {
min-height: 41rem;
}

.table-column-photo, .table-column-actions {
width: 2em;
}

.scroll-container {
width: 100%;
overflow-x: auto;
}

td, th {
vertical-align: middle;
}
}
36 changes: 22 additions & 14 deletions apps/showcase/src/components/showcase/sdk/sdk-pres.template.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="card mb-3">
<div class="card-body">
<form>
<div class="row">
<div class="row gap-3">
<label for="pet-name" class="col-xs-3 col-sm-auto col-form-label">Name</label>
<div class="col-xs-3 col-sm-auto">
<input
Expand All @@ -12,8 +12,15 @@
[ngModel]="petName()" (ngModelChange)="petName.set($event)"
/>
</div>
<div class="col-xs-3 col-sm-auto">
<o3r-otter-picker-pres
[id]="'pet-image'"
name="petImage"
[ngModel]="petImage()" (ngModelChange)="petImage.set($event)"
></o3r-otter-picker-pres>
</div>
<div class="col-xs-3 col-sm-auto mt-2 mt-sm-0">
<button class="btn btn-secondary w-100 w-sm-auto" (click)="create()">Create a pet</button>
<button class="btn btn-secondary w-100 w-sm-auto" (click)="create()">Create a pet</button>
</div>
</div>
</form>
Expand All @@ -38,34 +45,34 @@
<span class="visually-hidden">Loading...</span>
</div>
<div class="text-danger" *ngIf="hasErrors()">
Failed to load the list <button class="btn btn-md btn-danger" (click)="reload()">Retry</button>
Failed to load the list
<button class="btn btn-md btn-danger" (click)="reload()">Retry</button>
</div>
</div>
</div>
<div class="table-container scroll-container">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col" class="table-column-photo">Icon</th>
<th scope="col">Name</th>
<th scope="col">Category</th>
<th scope="col">Tags</th>
<th scope="col">Actions</th>
<th scope="col" class="table-column-actions">Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let pet of displayedPets()">
<th scope="row">{{ pet.id }}</th>
<td>
<ngb-highlight [result]="pet.name" [term]="searchTerm()"></ngb-highlight>
</td>
<td>
<ngb-highlight [result]="pet.category?.name" [term]="searchTerm()"></ngb-highlight>
<img width="34" height="34" [src]="baseUrl+icon" alt="{{icon}}" *ngIf="pet.photoUrls?.[0] as icon" />
</td>
<th scope="row">
<ngb-highlight [result]="pet.name" [term]="searchTerm()"></ngb-highlight>
</th>
<th><ngb-highlight [result]="getTags(pet)" [term]="searchTerm()"></ngb-highlight></th>
<td>
<ngb-highlight [result]="getTags(pet)" [term]="searchTerm()"></ngb-highlight>
<button class="btn btn-danger btn-sm" title="Delete" (click)="delete(pet)"><i class="bi bi-trash"></i>
</button>
</td>
<td><button class="btn btn-danger btn-sm" title="Delete" (click)="delete(pet)"><i class="bi bi-trash"></i></button></td>
</tr>
</tbody>
</table>
Expand All @@ -79,7 +86,8 @@
[maxSize]="10"
></ngb-pagination>

<select class="form-select w-auto" name="pageSize" [ngModel]="pageSize()" (ngModelChange)="pageSize.set($event)">
<select class="form-select w-auto" name="pageSize" [ngModel]="pageSize()"
(ngModelChange)="pageSize.set($event)">
<option [ngValue]="10">10 items per page</option>
<option [ngValue]="50">50 items per page</option>
<option [ngValue]="100">100 items per page</option>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ export interface InPageNavLink {
})
export class InPageNavLinkDirective implements InPageNavLink, AfterViewInit {
/** HTML id of the h2 */
public id: string = '';
public id = '';

/** InnerText of the h2 */
public label: string = '';
public label = '';

private nativeElement: HTMLElement;

Expand All @@ -45,7 +45,6 @@ export class InPageNavLinkDirective implements InPageNavLink, AfterViewInit {

/**
* Scroll to the h2 HTML element
*
* @param e mouse event
*/
public scrollTo(e: MouseEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export class InPageNavPresService implements OnDestroy {

/**
* Initialize the navigation links list
*
* @param inPageNavLinkDirectives
*/
public initialize(inPageNavLinkDirectives: QueryList<InPageNavLink>) {
Expand Down
1 change: 1 addition & 0 deletions apps/showcase/src/components/utilities/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './otter-picker/index';
export * from './copy-text/index';
export * from './in-page-nav/index';
export * from './scroll-back-top/index';
Expand Down
2 changes: 2 additions & 0 deletions apps/showcase/src/components/utilities/otter-picker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './otter-picker-pres.component';

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { ChangeDetectionStrategy, Component, forwardRef, Input, signal, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { O3rComponent } from '@o3r/core';

@O3rComponent({ componentType: 'Component' })
@Component({
selector: 'o3r-otter-picker-pres',
standalone: true,
imports: [CommonModule, NgbDropdownModule],
templateUrl: './otter-picker-pres.template.html',
styleUrls: ['./otter-picker-pres.style.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => OtterPickerPresComponent),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OtterPickerPresComponent implements ControlValueAccessor {
/** ID of the html element used for selection */
@Input()
public id!: string;

/** Currently selected otter */
public selectedOtter = signal('');

/** List of available otters */
public otters = [
'/assets/otter.svg',
'/assets/mini-otters/astronotter.svg',
'/assets/mini-otters/bonotter.svg',
'/assets/mini-otters/c3potter.svg',
'/assets/mini-otters/colombotter.svg',
'/assets/mini-otters/djokotter.svg',
'/assets/mini-otters/hallowtter.svg',
'/assets/mini-otters/harry-otter.svg',
'/assets/mini-otters/jack-sparrowtter.svg',
'/assets/mini-otters/mandalotter.svg',
'/assets/mini-otters/mariotter.svg',
'/assets/mini-otters/neotter.svg',
'/assets/mini-otters/pizzaiotter.svg',
'/assets/mini-otters/ronaldotter.svg',
'/assets/mini-otters/sombrerotter.svg'
];

/** Base URL where the images can be fetched */
public baseUrl = location.href.split('/#', 1)[0];

private onChanges!: (val: string) => void;
private onTouched!: () => void;
private isDisabled = signal(false);

/**
* Select an otter and notify the parent
* @param otter
*/
public selectOtter(otter: string) {
this.selectedOtter.set(otter);
this.onChanges(otter);
this.onTouched();
}

/**
* Implements ControlValueAccessor
* @param fn
*/
public registerOnChange(fn: any): void {
this.onChanges = fn;
}

/**
* Implements ControlValueAccessor
* @param fn
*/
public registerOnTouched(fn: any): void {
this.onTouched = fn;
}

/**
* Implements ControlValueAccessor
* @param isDisabled
*/
public setDisabledState(isDisabled: boolean): void {
this.isDisabled.set(isDisabled);
}

/**
* Implements ControlValueAccessor
* @param obj
*/
public writeValue(obj: any): void {
this.selectedOtter.set(obj);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { OtterPickerPresComponent } from './otter-picker-pres.component';

describe('OtterPickerPresComponent', () => {
let component: OtterPickerPresComponent;
let fixture: ComponentFixture<OtterPickerPresComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [OtterPickerPresComponent]
});
fixture = TestBed.createComponent(OtterPickerPresComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
o3r-otter-picker-pres {
.dropdown-menu {
flex-wrap: wrap;
justify-content: space-around;

&.show {
display: flex;
}

.dropdown-item {
display: inline-block;
width: auto;
}
}

.otter-dropdown {
min-width: 9em;

&.selected {
padding-top: 0;
padding-bottom: 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div ngbDropdown class="d-inline-block w-100">
<button type="button" class="btn btn-outline-primary otter-dropdown w-100" [class.selected]="!!selectedOtter()" [id]="id" ngbDropdownToggle>
<div class="w-100" *ngIf="selectedOtter()"><img [src]="baseUrl+selectedOtter()" width="34" height="34" /></div>
<span *ngIf="!selectedOtter()">Pick an icon</span>
</button>
<div ngbDropdownMenu [attr.aria-labelledby]="id">
<button ngbDropdownItem (click)="selectOtter('')">None</button>
<button ngbDropdownItem *ngFor="let otter of otters" (click)="selectOtter(otter)">
<img [src]="baseUrl+otter" width="45" height="45" />
</button>
</div>
</div>

This file was deleted.

2 changes: 0 additions & 2 deletions apps/showcase/src/facts/trip/trip.facts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export class TripFactsService extends FactsService<TripFacts> {

/**
* Update the destination
*
* @param destination
*/
public updateDestination(destination: string | null) {
Expand All @@ -38,7 +37,6 @@ export class TripFactsService extends FactsService<TripFacts> {

/**
* Update the outbound date
*
* @param outboundDate
*/
public updateOutboundDate(outboundDate: string | null) {
Expand Down
1 change: 1 addition & 0 deletions packages/@ama-sdk/core/src/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './clients/index';
export * from './fwk/index';
export * from './plugins/index';
export * from './utils/index';
5 changes: 5 additions & 0 deletions packages/@ama-sdk/core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './crypto';
export * from './encoder';
export * from './ie11';
export * from './json-token';
export * from './mime-types';
Loading

0 comments on commit 0899d9d

Please sign in to comment.