Commit 5a68a8aa authored by Laurent's avatar Laurent

Merge branch 'master' into inmediav2

parents 7a8db176 d829732c
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="__PACKAGE__"
android:versionCode="24"
android:versionName="0.0.24">
android:versionCode="35"
android:versionName="0.0.35">
<supports-screens
android:smallScreens="true"
......
......@@ -85,16 +85,22 @@ Label {
}
#loans .list-item .title {
.list-item .title {
background-color: #ccc;
}
#loans .list-item GridLayout.late .date_due{
.list-item GridLayout.late .date_due{
color: red;
}
#holds .status {
font-weight: bold;
}
.loan-item .title,
#novelties .title {
font-weight: bold;
}
......@@ -103,11 +109,12 @@ Label {
font-size: 14dip;
}
#accounts .list-item Label + Label + Label {
#accounts .list-item Label + Label {
margin-top: 2dip;
text-align: right;
}
#accounts .list-item Label + Label + Label + Label {
#accounts .list-item Label.count {
background-color: white;
border-radius: 40dip;
text-align: center;
......@@ -121,6 +128,12 @@ Label {
}
.loan-item {
text-align: center;
padding: 20dip;
}
/* forms */
.form_label { font-weight: bold; }
.error { color: red; padding:0; height: auto;}
......@@ -129,3 +142,9 @@ Label {
color:white;
}
TabView {
selected-tab-text-color: #185a9d;
android-selected-tab-highlight-color: #185a9d;
}
......@@ -2,8 +2,9 @@
import 'nativescript-i18n';
import * as app from 'tns-core-modules/application';
import {Database,Manager} from './models';
Database.open('prod');
import {Database, Manager, NSHTTPClient} from './models';
import * as config from "./config/config";
import { AccountsController } from './controllers/accounts';
import * as Frames from 'ui/frame';
function myReloadPage() {
......@@ -26,12 +27,10 @@ function myReloadPage() {
}
}
global.__onLiveSyncCore = myReloadPage;
import {Account} from './models';
import * as config from "./config/config";
Manager.url(config.MANAGER_URL);
import { AccountsController } from './controllers/accounts';
Database.open('prod');
let manager = new Manager(config.MANAGER_URL, new NSHTTPClient());
app.start({ moduleName: 'views/accounts/list',
bindingContext: new AccountsController()});
bindingContext: new AccountsController( manager ) });
......@@ -11,9 +11,11 @@ export class AccountsController extends Controller {
protected _portal: Portal = new Portal();
protected _portals: Array<MBPortal>;
protected _accounts: ObservableArray<Account>;
protected _manager: Manager;
public constructor() {
public constructor(manager: Manager) {
super();
this._manager = manager;
this._accounts = new ObservableArray<Account>();
this._refreshAccounts();
this.set('accounts', this._accounts);
......@@ -48,11 +50,11 @@ export class AccountsController extends Controller {
this.set('currently_edited', account);
this._saveAccount();
let library_controller = new LibraryController(account);
library_controller.doRefreshLoans();
let library_controller = new LibraryController(account, this._manager);
library_controller.doRefreshLoansAndHolds();
this.navigate({
moduleName: "views/library/loans",
moduleName: "views/library/items",
bindingContext: library_controller
});
}
......@@ -109,7 +111,7 @@ export class AccountsController extends Controller {
this._portals = new Array<MBPortal>();
let portals_cache = this._portals;
new Manager().portals().then( (portals) => {
this._manager.portals().then( (portals) => {
portals.map( (element) => { portals_cache.push(element); });
});
......@@ -132,8 +134,8 @@ export class AccountsController extends Controller {
public openAccountAction(args) {
let account = this._accounts.getItem(args.index);
this.navigate({moduleName: "views/library/loans",
bindingContext: new LibraryController(account)});
this.navigate({moduleName: "views/library/items",
bindingContext: new LibraryController(account, this._manager)});
}
......@@ -214,9 +216,7 @@ export class AccountsController extends Controller {
}
let portal_label = form.portals[form.selectedPortalIndex];
let portal: PortalAdapter = this
._portal
.adapters
let portal: PortalAdapter = Array.from(this._portal.adapters.values())
.filter((a) => {
return a.getLabel() == portal_label;
})[0];
......@@ -268,7 +268,7 @@ export class AccountsController extends Controller {
protected _populateWithAdapters(form): AccountsController {
form.portals = this._portal.adapters
form.portals = Array.from(this._portal.adapters.values())
.map((adapter) => { return adapter.getLabel(); })
.sort();
return this;
......
This diff is collapsed.
......@@ -56,4 +56,12 @@
<string name="card_number">Card number</string>
<string name="novelties">Novelties</string>
<string name="card_expire_at">Expire at</string>
<string name="holds">Holds</string>
<string name="no_holds">No holds. Pull to refresh.</string>
<string name="loans_and_holds">Loans / Holds</string>
<string name="library">Library</string>
<string name="do_loan">Loan item</string>
<string name="do_loan_barcode">Loan : %s</string>
<string name="enter_password">To finish the request, enter your password</string>
<string name="loan_title_date_due">%s, bring back for %s</string>
</resources>
......@@ -56,4 +56,12 @@
<string name="card_number">Numéro de tarjeta</string>
<string name="novelties">Nuevo</string>
<string name="card_expire_at">Vence en</string>
<string name="holds">Reservas</string>
<string name="no_holds">No hay reserva. Dezliza para refrescar.</string>
<string name="loans_and_holds">Prestamos / Reservas</string>
<string name="library">Biblioteca</string>
<string name="do_loan">Pedir prestado</string>
<string name="do_loan_barcode">Prestamo : %s</string>
<string name="enter_password">Para finalizar la solicitud, ingrese su contraseña</string>
<string name="loan_title_date_due">%s, para regresar a más tardar %s</string>
</resources>
......@@ -56,4 +56,12 @@
<string name="card_number">Numéro de carte</string>
<string name="novelties">Nouveautés</string>
<string name="card_expire_at">Expire le</string>
<string name="holds">Réservations</string>
<string name="no_holds">Aucune réservation. Tirez pour rafraîchir.</string>
<string name="loans_and_holds">Prêts / Réservations</string>
<string name="library">Bibliothèque</string>
<string name="do_loan">Emprunter</string>
<string name="do_loan_barcode">Emprunt : %s</string>
<string name="enter_password">Pour finaliser la demande, veuillez saisir votre mot de passe</string>
<string name="loan_title_date_due">%s, à retourner au plus tard le %s</string>
</resources>
import {Persistable, Serializable, DataSource} from './persistable';
import {Loan, Card} from '../models/';
import {Loan,
Hold,
Card,
Persistable,
Serializable,
DataSource} from '../models/';
export class Account extends Persistable {
protected _label: string = '';
protected _url: string = '';
protected _number_of_loans: number = 0;
protected _number_of_holds: number = 0;
protected _credentials: Object = new Object();
protected _card: Card = new Card();
protected _is_connected: boolean = false;
......@@ -45,12 +50,16 @@ export class Account extends Persistable {
}
public deleteChilds(datasource: DataSource): Persistable {
return this.deleteLoans(datasource);
public deleteChilds(datasource: DataSource): this {
this
.deleteLoans(datasource)
.deleteHolds(datasource);
datasource.delete(this._card);
return this;
}
public deleteLoans(datasource): Persistable {
public deleteLoans(datasource: DataSource): this {
this
.findLoans(datasource)
.forEach((loan) => {
......@@ -62,17 +71,49 @@ export class Account extends Persistable {
}
public setNumberOfLoans(number_of_loans: number) {
public deleteHolds(datasource): this {
this
.findHolds(datasource)
.forEach((hold) => {
datasource.delete(hold);
});
this._number_of_holds = 0;
return this;
}
public setNumberOfLoans(number_of_loans: number): this {
this._number_of_loans = number_of_loans;
return this;
}
public setNumberOfHolds(number_of_holds: number): this {
this._number_of_holds = number_of_holds;
return this;
}
public findLoans(datasource: DataSource): Array<Loan> {
return this
._findAll(datasource, Loan)
.sort((a, b) => {
return a.getDateDue().localeCompare(b.getDateDue());
})
}
public findHolds(datasource: DataSource): Array<Hold> {
return this._findAll(datasource, Hold);
}
protected _findAll<T extends Persistable>(datasource: DataSource, modelClass:{new():T;}): Array<T> {
return datasource
.findAll(Loan)
.filter((loan) => {
return loan.getAccount() && (loan.getAccount().getId() == this.getId());
.findAll(modelClass)
.filter((obj) => {
return obj.isOwnedBy(this);
});
}
......@@ -82,6 +123,11 @@ export class Account extends Persistable {
}
public numberOfHolds(): number {
return this._number_of_holds;
}
public getUrl(): string {
this._url.replace(new RegExp('/$'), '');
if (!this._url.includes('://'))
......@@ -151,6 +197,7 @@ export class Account extends Persistable {
.set('url', this._url)
.set('credentials', this._credentials)
.set('number_of_loans', this._number_of_loans)
.set('number_of_holds', this._number_of_holds)
.set('card', this._card.getId());
}
......@@ -159,9 +206,17 @@ export class Account extends Persistable {
this._label = serializable.get('label');
this._url = serializable.get('url');
this._credentials = serializable.get('credentials');
this._card = serializable.get('card', Card);
if (!this._card)
this._card = new Card();
this._number_of_loans = serializable.get('number_of_loans');
if (!this._number_of_loans)
this._number_of_loans = 0;
this._number_of_holds = serializable.get('number_of_holds');
if (!this._number_of_holds)
this._number_of_holds = 0;
}
}
......@@ -40,6 +40,9 @@ export class Database implements DataSource {
public save(model: Persistable): Database {
if (!model.validate())
return this;
model.beforeSave(this);
(new DatabaseTransaction(this, model)).save();
......@@ -52,11 +55,12 @@ export class Database implements DataSource {
public delete(model: Persistable): Database {
let dependents = model.deleteChilds(this);
this._db.deleteDocument(model.getId());
model.setId(undefined);
return this;
}
public findAll(modelClass:any): any {
public findAll<T extends Persistable>(modelClass:{new():T;}): Array<T> {
return this
._views
.findAll(modelClass,
......@@ -66,8 +70,8 @@ export class Database implements DataSource {
}
public find(modelClass:any, id:string): any {
if (null == id)
public find<T extends Persistable>(modelClass:{new():T;}, id:string): T {
if (!id)
return null;
let document = this._db.getDocument(id);
......@@ -78,7 +82,7 @@ export class Database implements DataSource {
}
public createView(name:string, revision:string, callback:any) {
public createView(name:string, revision:string, callback:Function) {
return this._views.createView(name, revision, callback);
}
......@@ -98,8 +102,8 @@ export class Database implements DataSource {
}
protected _materialize(modelClass: any, document:any): any {
let model: Persistable = new modelClass(document._id);
protected _materialize<T extends Persistable>(modelClass: {new(id:string):T;}, document:any): T {
let model: T = new modelClass(document._id);
model.materializeFrom(new DatabaseDocument(this, document));
return model;
}
......@@ -118,7 +122,7 @@ class DatabaseViews {
}
public createView(name, revision, callback) {
public createView(name:string, revision:string, callback:Function): DatabaseViews {
this._declared_views.add(name);
this._db.createView(name, revision, callback);
return this;
......@@ -132,8 +136,8 @@ class DatabaseViews {
}
public findAll(modelClass:any, callback:any) {
let models = [];
public findAll<T extends Persistable>(modelClass:{new():T;}, callback:Function): Array<T> {
let models: Array<T> = new Array<T>();
for(let document of this.executeQueryForModel(modelClass.name)) {
models.push(callback(document));
......@@ -170,7 +174,7 @@ class DatabaseTransaction {
}
public save() {
public save(): DatabaseTransaction {
let document = new DatabaseDocument(this._db);
document.set("model", this._model.constructor['name']);
......@@ -182,14 +186,14 @@ class DatabaseTransaction {
}
protected _insert(document) {
protected _insert(document): DatabaseTransaction {
let id = this._db.createDocument(document.serialize());
this._model.setId(id);
return this;
}
protected _update(document) {
protected _update(document): DatabaseTransaction {
this._db.updateDocument(this._model.getId(),
document.serialize());
return this;
......@@ -209,13 +213,13 @@ class DatabaseDocument implements Serializable {
}
public set(name, value): Serializable {
public set(name:string, value:number|string|boolean): Serializable {
this._properties[name] = (null == value ? '' : value);
return this;
}
public get(name, modelClass?: any) {
public get<T extends Persistable>(name:string, modelClass?:{new():T;}): number|string|boolean|T {
return modelClass
? this._db.find(modelClass, this._properties[name])
: this._properties[name];
......
import {ItemOperation, Serializable} from '../models';
export class Hold extends ItemOperation {
protected _hold_id: string;
protected _status: string;
public setHoldId(hold_id: string): this {
this._hold_id = hold_id;
return this;
}
public getHoldId(): string {
return this._hold_id;
}
public setStatus(status: string): this {
this._status = status;
return this;
}
public getStatus(): string {
return this._status;
}
public serializeOn(serializable: Serializable) {
super.serializeOn(serializable);
serializable
.set('hold_id', this._hold_id)
.set('status', this._status);
}
public materializeFrom(serializable: Serializable) {
super.materializeFrom(serializable);
this._hold_id = serializable.get('hold_id');
this._status = serializable.get('status');
}
}
import {HTTPClient} from './http-client';
import {Cookies} from '../';
import * as http from 'http';
export class NSHTTPClient implements HTTPClient {
public request(options: any): Promise<http.HttpResponse> {
console.dir(options);
return http.request(options);
console.dir([ 'on request', (new Cookies()).getCookies(), options]);
return http.request(options).then( (response) => {
console.dir([ 'on response', (new Cookies()).getCookies(), response.headers]);
return response;
});
}
}
export {Persistable, Serializable, DataSource} from './persistable';
export {Database} from './database';
export {Account} from './account';
export {ItemOperation} from './item-operation';
export {Loan} from './loan';
export {Database} from './database';
export {Hold} from './hold';
export {Portal} from './portal';
export {HTTPClient} from './http/http-client';
export {NSHTTPClient} from './http/ns-http-client';
......@@ -12,6 +15,8 @@ export {PortalDetectionFail} from './portal/portal-detection-fail';
export {Cookies} from './cookies/cookies';
export {Manager, MBPortal} from './manager';
export {Record} from './record';
export {Item} from './item';
export {Novelties} from './novelties';
export {Card} from './card';
export {Iso8601Date} from './iso8601_date';
import {Account, Persistable, Serializable} from '../models/';
export abstract class ItemOperation extends Persistable {
protected _account: Account;
protected _item: any = {};
public getRecordId(): string {
return this._item.record_id;
}
public setRecordId(record_id: string): this {
this._item.record_id = record_id;
return this;
}
public getRecordUrl(): string {
return this._item.record_url;
}
public setRecordUrl(record_url: string): this {
this._item.record_url = record_url;
return this;
}
public getRecordThumbnail(): string {
return this._item.record_thumbnail;
}
public setRecordThumbnail(record_thumbnail: string): this {
this._item.record_thumbnail = record_thumbnail;
return this;
}
public setTitle(title:string): this {
this._item.title = title;
return this;
}
public getTitle():string {
return this._item.title;
}
public setAuthor(author:string): this {
this._item.author = author;
return this;
}
public getAuthor():string {
return this._item.author;
}
public setLibrary(library: string): this {
this._item.library = library;
return this;
}
public getLibrary(): string {
return this._item.library;
}
public setAccount(account: Account): this {
this._account = account;
return this;
}
public getAccount(): Account {
return this._account;
}
public validate(): boolean {
return this._account
? true
: false;
}
public isOwnedBy(other: Account): boolean {
return this._account && this._account.getId() == other.getId();
}
public serializeOn(serializable: Serializable) {
serializable
.set('item', this._item)
.set('account', this._account.getId());
}
public materializeFrom(serializable: Serializable) {
this._item = serializable.get("item") || {};
this._account = serializable.get('account', Account);
}
}
import {Record} from '../models/';
export class Item {
protected _barcode: string;
protected _record: Record;
public constructor(barcode: string) {
this._barcode = barcode;
this._record = new Record();
}
public getBarcode(): string {
return this._barcode;
}
public setRecordId(id: string): this {
this._record.setId(id);
return this;
}
public setThumbnailUrl(url: string): this {
this._record.setThumbnailUrl(url);
return this;
}
public setTitle(title: string): this {
this._record.setTitle(title);
return this;
}
public setAuthor(author: string): this {
this._record.setAuthor(author);
return this;
}
public getThumbnailUrl(): string {
return this._record.getThumbnailUrl();
}
get thumbnail_url(): string {
return this.getThumbnailUrl();
}