Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client-app/src/core/svc/GitHubService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ export class GitHubService extends HoistService {
});
}
})
.catch(e => XH.handleException(e, {showAlert: false, showAsError: false}));
.catchDefault({showAlert: false, showAsError: false});
}
}
25 changes: 14 additions & 11 deletions client-app/src/core/svc/PortfolioService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,23 @@ export class PortfolioService extends HoistService {
async getLivePositionsAsync(
dims: string[],
topic: string,
ctx?: CallContext,
maxPositions: number = this.MAX_POSITIONS
) {
return this.rootSpan('getLivePositions').run(async ctx => {
const session = await ctx.fetchJson({
url: 'portfolio/livePositions',
params: {
dims: dims.join(','),
maxPositions,
channelKey: XH.webSocketService.channelKey,
topic
}
return this.runOnOptional(ctx)
.newSpan('getLivePositions')
.run(async ctx => {
const session = await ctx.fetchJson({
url: 'portfolio/livePositions',
params: {
dims: dims.join(','),
maxPositions,
channelKey: XH.webSocketService.channelKey,
topic
}
});
return new PositionSession(session);
});
return new PositionSession(session);
});
}

/**
Expand Down
23 changes: 8 additions & 15 deletions client-app/src/examples/contact/DirectoryPanelModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,15 @@ export class DirectoryPanelModel extends HoistModel {
//------------------------
override async doLoadAsync(loadSpec: LoadSpec) {
const {gridModel} = this;
const contacts = await XH.contactService.getContactsAsync(loadSpec);

try {
const contacts = await XH.contactService.getContactsAsync();
if (loadSpec.isStale) return;

runInAction(() => {
this.tagList = uniq(contacts.flatMap(it => it.tags ?? [])).sort() as string[];
this.locationList = uniq(contacts.map(it => it.location)).sort() as string[];
});

gridModel.loadData(contacts);
await gridModel.preSelectFirstAsync();
} catch (e) {
if (loadSpec.isStale) return;
XH.handleException(e);
}
runInAction(() => {
this.tagList = uniq(contacts.flatMap(it => it.tags ?? [])).sort() as string[];
this.locationList = uniq(contacts.map(it => it.location)).sort() as string[];
});

gridModel.loadData(contacts);
await gridModel.preSelectFirstAsync();
}

private updateLocationFilter() {
Expand Down
12 changes: 5 additions & 7 deletions client-app/src/examples/contact/details/DetailsPanelModel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {XH, HoistModel, managed} from '@xh/hoist/core';
import {HoistModel, managed} from '@xh/hoist/core';
import {FormModel} from '@xh/hoist/cmp/form';
import {required} from '@xh/hoist/data/validation/constraints';
import {makeObservable, observable, action} from '@xh/hoist/mobx';
Expand Down Expand Up @@ -56,12 +56,10 @@ export class DetailsPanelModel extends HoistModel {
return;
}

try {
await directoryPanelModel.updateContactAsync(currentRecord.id, formModel.getData(true));
formModel.readonly = true;
} catch (e) {
XH.handleException(e);
}
return directoryPanelModel
.updateContactAsync(currentRecord.id, formModel.getData(true))
.then(() => (formModel.readonly = true))
.catchDefault();
}

@action
Expand Down
26 changes: 14 additions & 12 deletions client-app/src/examples/contact/svc/ContactService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {HoistService, persist, XH} from '@xh/hoist/core';
import {CallContext, HoistService, persist, XH} from '@xh/hoist/core';
import {action, observable, makeObservable} from '@xh/hoist/mobx';
import {without} from 'lodash';

Expand All @@ -25,17 +25,19 @@ export class ContactService extends HoistService {
makeObservable(this);
}

async getContactsAsync() {
return this.rootSpan('getContacts').run(ctx =>
ctx.fetchJson({url: 'contacts'}).tap(ret => {
ret.forEach(it => {
it.isFavorite = this.userFaves.includes(it.id);
it.profilePicture = `../../public/contact-images/${
it.profilePicture ?? 'no-profile.png'
}`;
});
})
);
async getContactsAsync(ctx?: CallContext) {
return this.runOnOptional(ctx)
.newSpan('getContacts')
.run(ctx =>
ctx.fetchJson({url: 'contacts'}).tap(ret => {
ret.forEach(it => {
it.isFavorite = this.userFaves.includes(it.id);
it.profilePicture = `../../public/contact-images/${
it.profilePicture ?? 'no-profile.png'
}`;
});
})
);
}

async updateContactAsync(id, update) {
Expand Down
28 changes: 11 additions & 17 deletions client-app/src/examples/portfolio/PortfolioModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,17 @@ export class PortfolioModel extends HoistModel {
await waitFor(() => wsService.connected).catch(() =>
this.logError('WebSocket service failed to connect')
);
if (loadSpec.isStale) return;

try {
const session = await XH.portfolioService.getLivePositionsAsync(dims, 'mainApp');
if (loadSpec.isStale) return;

store.loadData([session.initialPositions.root]);
session.onUpdate = ({data}) => {
posGridModel.loadTimestamp = Date.now();
store.updateData(data);
};

this.session = session;
await posGridModel.gridModel.preSelectFirstAsync();
} catch (e) {
XH.handleException(e);
}
loadSpec.abortIfNeeded();

const session = await XH.portfolioService.getLivePositionsAsync(dims, 'mainApp', loadSpec);
store.loadData([session.initialPositions.root]);
session.onUpdate = ({data}) => {
posGridModel.loadTimestamp = Date.now();
store.updateData(data);
};

this.session = session;
await posGridModel.gridModel.preSelectFirstAsync();
}

//------------------------
Expand Down
18 changes: 5 additions & 13 deletions client-app/src/examples/portfolio/detail/charts/LineChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,15 @@ class LineChartModel extends HoistModel {

override async doLoadAsync(loadSpec: LoadSpec) {
const {symbol, chartModel} = this;

if (!symbol) {
chartModel.clear();
return;
}
chartModel.setSeries(await XH.portfolioService.getLineChartSeriesAsync({symbol}, loadSpec));
}

try {
const series = await XH.portfolioService.getLineChartSeriesAsync({symbol}, loadSpec);
if (loadSpec.isStale) return;

chartModel.setSeries(series);
} catch (e) {
if (loadSpec.isAutoRefresh || loadSpec.isStale) return;

chartModel.clear();
XH.handleException(e, {showAlert: false});
throw e;
}
override handleLoadException(e: unknown) {
this.chartModel.clear();
XH.handleException(e, {showAlert: false});
}
}
18 changes: 5 additions & 13 deletions client-app/src/examples/portfolio/detail/charts/OHLCChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,15 @@ class OHLCChartModel extends HoistModel {

override async doLoadAsync(loadSpec: LoadSpec) {
const {symbol, chartModel} = this;

if (!symbol) {
chartModel.clear();
return;
}
chartModel.setSeries(await XH.portfolioService.getOHLCChartSeriesAsync(symbol, loadSpec));
}

try {
const series = await XH.portfolioService.getOHLCChartSeriesAsync(symbol, loadSpec);
if (loadSpec.isStale) return;

chartModel.setSeries(series);
} catch (e) {
if (loadSpec.isAutoRefresh || loadSpec.isStale) return;

chartModel.clear();
XH.handleException(e, {showAlert: false});
throw e;
}
override handleLoadException(e: unknown) {
this.chartModel.clear();
XH.handleException(e, {showAlert: false});
}
}
31 changes: 13 additions & 18 deletions client-app/src/examples/portfolio/detail/orders/OrdersModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,30 +109,25 @@ export class OrdersModel extends HoistModel {

override async doLoadAsync(loadSpec: LoadSpec) {
const {gridModel, positionId, dashViewModel} = this;

if (isNil(positionId)) {
gridModel.clear();
return;
}

try {
const orders = await XH.portfolioService.getOrdersAsync(positionId, loadSpec),
sparklineSeries = await XH.portfolioService.getSparklineSeriesAsync(
uniq(map(orders, 'symbol')),
loadSpec
);
if (loadSpec.isStale) return;

dashViewModel.titleDetails = `(${orders.length})`;
orders.forEach(order => (order.closingPrices = sparklineSeries[order.symbol]));
gridModel.loadData(orders);
const orders = await XH.portfolioService.getOrdersAsync(positionId, loadSpec),
sparklineSeries = await XH.portfolioService.getSparklineSeriesAsync(
uniq(map(orders, 'symbol')),
loadSpec
);

await gridModel.preSelectFirstAsync();
} catch (e) {
if (loadSpec.isAutoRefresh || !loadSpec.isStale) return;
dashViewModel.titleDetails = `(${orders.length})`;
orders.forEach(order => (order.closingPrices = sparklineSeries[order.symbol]));
gridModel.loadData(orders);
await gridModel.preSelectFirstAsync();
}

gridModel.clear();
XH.handleException(e);
}
override handleLoadException(e: unknown) {
this.gridModel.clear();
XH.handleException(e);
}
}
39 changes: 16 additions & 23 deletions client-app/src/examples/recalls/RecallsPanelModel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {GridModel, localDateCol} from '@xh/hoist/cmp/grid';
import {HoistModel, LoadSpec, managed, persist, XH} from '@xh/hoist/core';
import {HoistModel, LoadSpec, managed, persist} from '@xh/hoist/core';
import {compactDateRenderer} from '@xh/hoist/format';
import {Icon} from '@xh/hoist/icon/Icon';
import {bindable, makeObservable} from '@xh/hoist/mobx';
Expand Down Expand Up @@ -120,30 +120,23 @@ export class RecallsPanelModel extends HoistModel {
//------------------------
override async doLoadAsync(loadSpec: LoadSpec) {
const {gridModel} = this;
return this.runOn(loadSpec)
.newSpan('load')
.run(async ctx => {
let entries = await ctx.fetchJson({
url: 'recalls',
params: {searchQuery: this.searchQuery}
});

try {
await this.runOn(loadSpec)
.newSpan('load')
.run(async ctx => {
let entries = await ctx.fetchJson({
url: 'recalls',
params: {searchQuery: this.searchQuery}
});

if (loadSpec.isStale) return;

// Approximate (and enforce) a unique id for this rather opaque API
entries.forEach(it => {
it.id = it.openfda.brand_name[0] + it.recall_number;
});
entries = uniqBy(entries, 'id');

gridModel.loadData(entries);
await gridModel.preSelectFirstAsync();
// Approximate (and enforce) a unique id for this rather opaque API
entries.forEach(it => {
it.id = it.openfda.brand_name[0] + it.recall_number;
});
} catch (e) {
XH.handleException(e);
}
entries = uniqBy(entries, 'id');

gridModel.loadData(entries);
await gridModel.preSelectFirstAsync();
});
}

private processRecord(rawRec) {
Expand Down
9 changes: 2 additions & 7 deletions client-app/src/examples/weather/WeatherDashModel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {HoistModel, LoadSpec, managed, persist, XH} from '@xh/hoist/core';
import {HoistModel, LoadSpec, managed, persist} from '@xh/hoist/core';
import {ViewManagerModel} from '@xh/hoist/cmp/viewmanager';
import {DashCanvasModel} from '@xh/hoist/desktop/cmp/dash';
import {bindable, makeObservable, observable, runInAction} from '@xh/hoist/mobx';
Expand Down Expand Up @@ -138,7 +138,7 @@ export class WeatherDashModel extends HoistModel {
const {selectedCity} = this;
if (!selectedCity) return;

await this.runOn(loadSpec)
return this.runOn(loadSpec)
.newSpan('dashLoad')
.run(async ctx => {
ctx.span.setTags({city: selectedCity});
Expand All @@ -148,16 +148,11 @@ export class WeatherDashModel extends HoistModel {
ctx.fetchJson({url: 'weather/current', params}),
ctx.fetchJson({url: 'weather/forecast', params})
]);
if (loadSpec.isStale) return;

runInAction(() => {
this.currentWeather = currentWeather;
this.forecast = forecast;
});
})
.catch(e => {
if (loadSpec.isAutoRefresh || loadSpec.isStale) return;
XH.handleException(e);
});
}
}