Skip to content

Commit

Permalink
Merge branch 'develop' into advanced-routing
Browse files Browse the repository at this point in the history
  • Loading branch information
amcclain committed Mar 26, 2024
2 parents eaba6a6 + 047c9c6 commit b2c8e84
Show file tree
Hide file tree
Showing 18 changed files with 1,024 additions and 835 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]

jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'

# Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

- name: Build with Gradle Wrapper
run: ./gradlew build

# NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html).
# If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version.
#
# - name: Setup Gradle
# uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
# with:
# gradle-version: '8.5'
#
# - name: Build with Gradle 8.5
# run: gradle build

dependency-submission:

runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'

# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
# See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
10 changes: 8 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,16 @@ if (parseBoolean(runHoistInline)) {
}

dependencies {
implementation "org.bitbucket.b_c:jose4j:0.7.12"
// For server-side JWT validation.
implementation "org.bitbucket.b_c:jose4j:0.9.6"

// Database drivers - H2 for temporary in-memory DB with `useH2: true` in instanceConfig YAML
// MySQL for deployed instances, or more stateful local workstation setups.
runtimeOnly "com.h2database:h2:2.2.224"
runtimeOnly "mysql:mysql-connector-java:8.0.33"
developmentOnly "io.methvin:directory-watcher:0.15.0"

// For hot reloading
developmentOnly "io.methvin:directory-watcher:0.15.0"
if (parseBoolean(enableHotSwap)) {
developmentOnly "io.xh:groovyReset:1.0"
}
Expand Down
2 changes: 1 addition & 1 deletion client-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@ag-grid-enterprise/sparklines": "~30.2.1",
"@auth0/auth0-spa-js": "~1.22.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@xh/hoist": "^62.0.0-SNAPSHOT",
"@xh/hoist": "^63.0.0-SNAPSHOT",
"@xh/package-template": "~2.0.0",
"core-js": "3.x",
"highcharts": "11.x",
Expand Down
5 changes: 5 additions & 0 deletions client-app/src/desktop/AppModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ export class AppModel extends BaseAppModel {
{name: 'placeholder', path: '/placeholder'},
{name: 'popups', path: '/popups'},
{name: 'timestamp', path: '/timestamp'},
{
name: 'simpleRouting',
path: '/simpleRouting',
children: [{name: 'recordId', path: '/:recordId'}]
},
{
name: 'advancedRouting',
path: '/advancedRouting',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const roadmapViewItem = hoistCmp.factory({
? popover({
popoverClassName: 'tb-roadmap__popover',
minimal: true,
target: truncate(name, {length: 55, omission: ' ...'}),
item: truncate(name, {length: 55, omission: ' ...'}),
content: name
})
: name
Expand All @@ -44,7 +44,7 @@ export const roadmapViewItem = hoistCmp.factory({
minimal: true,
interactionKind: 'hover',
position: 'top',
target: div({
item: div({
className: 'tb-roadmap-item__statusIcon',
item: getStatusIcon(status)
}),
Expand All @@ -62,7 +62,7 @@ export const roadmapViewItem = hoistCmp.factory({
minimal: true,
interactionKind: 'hover',
position: 'left-top',
target: span(' ...'),
item: span(' ...'),
content: div({
items: breakUpDescription(description)
})
Expand Down Expand Up @@ -120,7 +120,7 @@ function getGitIcon(gitLinks) {
} else {
return popover({
minimal: true,
target: button({icon: gitIcon}),
item: button({icon: gitIcon}),
content: menu({items: getGitMenuItems(gitLinks)})
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
background-color: var(--xh-bg-alt);
padding: var(--xh-pad-half-px);

.bp4-popover-content {
.bp5-popover-content {
background-color: var(--xh-bg-alt) !important;
}

Expand Down
6 changes: 3 additions & 3 deletions client-app/src/desktop/tabs/layout/widgets/ChartWidget.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.xh-app .tb-chart-widget__buttons .xh-button.bp4-button.xh-button--enabled:focus,
.xh-app.xh-dark .tb-chart-widget__buttons .xh-button.bp4-button.xh-button--enabled:focus,
.xh-app.xh-dark.bp4-dark .tb-chart-widget__buttons .xh-button.bp4-button.xh-button--enabled:focus {
.xh-app .tb-chart-widget__buttons .xh-button.bp5-button.xh-button--enabled:focus,
.xh-app.xh-dark .tb-chart-widget__buttons .xh-button.bp5-button.xh-button--enabled:focus,
.xh-app.xh-dark.bp5-dark .tb-chart-widget__buttons .xh-button.bp5-button.xh-button--enabled:focus {
outline: none !important;
}
2 changes: 2 additions & 0 deletions client-app/src/desktop/tabs/other/OtherTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {placeholderPanel} from './PlaceholderPanel';
import {popupsPanel} from './PopupsPanel';
import {relativeTimestampPanel} from './relativetimestamp/RelativeTimestampPanel';
import {advancedRoutingPanel} from './routing/AdvancedRoutingPanel';
import {simpleRoutingPanel} from './routing/SimpleRoutingPanel';

export const otherTab = hoistCmp.factory(() =>
tabContainer({
Expand Down Expand Up @@ -46,6 +47,7 @@ export const otherTab = hoistCmp.factory(() =>
{id: 'placeholder', title: 'Placeholder', content: placeholderPanel},
{id: 'popups', content: popupsPanel},
{id: 'timestamp', content: relativeTimestampPanel},
{id: 'simpleRouting', content: simpleRoutingPanel},
{id: 'advancedRouting', content: advancedRoutingPanel}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ const displayOptions = hoistCmp.factory<ExceptionHandlerModel>(({model}) =>
alignItems: 'center',
items: [
label({
className: `bp4-control bp4-switch bp4-inline bp4-align-right xh-input xh-switch-input${
!model.showAlert ? ' bp4-disabled xh-input-disabled' : ''
className: `bp5-control bp5-switch bp5-inline bp5-align-right xh-input xh-switch-input${
!model.showAlert ? ' bp5-disabled xh-input-disabled' : ''
}`,
item: 'Alert Type'
}),
Expand Down
10 changes: 5 additions & 5 deletions client-app/src/desktop/tabs/other/formats/Styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@
}
}

.bp4-form-content {
.bp5-form-content {
display: flex;
}

.bp4-form-group {
.bp5-form-group {
margin: 0;
padding: var(--xh-pad-half-px);
float: right;

.bp4-label {
.bp5-label {
margin-bottom: 2px;

.bp4-text-muted {
.bp5-text-muted {
visibility: hidden;
font-family: var(--xh-font-family-mono);
background-color: var(--xh-bg-alt);
Expand All @@ -64,7 +64,7 @@
}
}

.bp4-form-helper-text {
.bp5-form-helper-text {
margin-left: 20px;
}
}
Expand Down
110 changes: 110 additions & 0 deletions client-app/src/desktop/tabs/other/routing/SimpleRoutingPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {grid, GridModel} from '@xh/hoist/cmp/grid';
import {creates, hoistCmp, HoistModel, LoadSpec, managed, XH} from '@xh/hoist/core';
import {panel} from '@xh/hoist/desktop/cmp/panel';
import {Icon} from '@xh/hoist/icon';
import React from 'react';
import {wrapper} from '../../../common';

export const simpleRoutingPanel = hoistCmp.factory({
displayName: 'SimpleRoutingPanel',
model: creates(() => new SimpleRoutingPanelModel()),

render({model}) {
const routedUrl = `${window.location.origin}/app/other/simpleRouting/123`;
return wrapper({
description: [
<p>
Hoist provides functionality for route parameters to interact with UI
components. The grid below has its selected record synced with a routable URL.
</p>,
<p>
Given a URL such as <a href={routedUrl}>{routedUrl}</a>, where <code>123</code>{' '}
is a record ID, we can auto-select the matching record in the grid. Updates to
application state can be pushed back to the URL - try selecting a different
record in the grid and observe the URL change.
</p>,
<p>
Note that this routing relies on an appropriate route path being defined in the
config returned by <code>AppModel.getRoutes()</code>.
</p>
],
item: panel({
title: 'Simple Routing',
icon: Icon.gridPanel(),
item: grid(),
height: 500,
width: 700
})
});
}
});

@managed
class SimpleRoutingPanelModel extends HoistModel {
private readonly BASE_ROUTE = 'default.other.simpleRouting';

@managed gridModel = new GridModel({
columns: [{field: 'id'}, {field: 'company', flex: 1}]
});

constructor() {
super();
this.addReaction(
{
// Track lastLoadCompleted to sync route -> grid after initial load.
track: () => [XH.routerState.params, this.lastLoadCompleted],
run: () => this.updateGridFromRoute()
},
{
track: () => this.gridModel.selectedId,
run: () => this.updateRouteFromGrid()
}
);
}

async updateGridFromRoute() {
const {gridModel, BASE_ROUTE} = this,
{name: currRouteName, params} = XH.routerState,
{recordId} = params;

// No-op if not on the current base route.
if (!currRouteName.startsWith(BASE_ROUTE)) return;

if (recordId) {
await gridModel.selectAsync(Number(recordId));

// Check and alert if requested record not found, and clean up route to match.
if (!gridModel.selectedRecord) {
XH.dangerToast(`Record ${recordId} not found.`);
XH.navigate(BASE_ROUTE, {replace: true});
}
} else {
gridModel.clearSelection();
}
}

updateRouteFromGrid() {
const {gridModel, BASE_ROUTE} = this,
{name: currRouteName, params} = XH.routerState,
{selectedId} = gridModel,
{recordId} = params;

// No-op if not on the current base route, or if route and selection already match.
if (!currRouteName.startsWith(BASE_ROUTE) || recordId === selectedId) return;

if (selectedId) {
XH.navigate(
'default.other.simpleRouting.recordId',
{recordId: selectedId},
{replace: true} // avoids adding steps to browser history
);
} else {
XH.navigate('default.other.simpleRouting', {replace: true});
}
}

override async doLoadAsync(loadSpec: LoadSpec) {
const {trades} = await XH.fetchJson({url: 'trade', loadSpec});
this.gridModel.loadData(trades);
}
}
23 changes: 20 additions & 3 deletions client-app/src/desktop/tabs/panels/BasicPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import React from 'react';
import {creates, hoistCmp, XH} from '@xh/hoist/core';
import {div, filler, p} from '@xh/hoist/cmp/layout';
import {menu, menuItem, popover} from '@xh/hoist/kit/blueprint';
import {wrapper} from '../../common';
import {panel} from '@xh/hoist/desktop/cmp/panel';
import {select, switchInput} from '@xh/hoist/desktop/cmp/input';
import {toolbarSep} from '@xh/hoist/desktop/cmp/toolbar';
import {button} from '@xh/hoist/desktop/cmp/button';
import {Icon} from '@xh/hoist/icon';
import {wait} from '@xh/hoist/promise';
import {clipboardMenuItem} from '@xh/hoist/desktop/cmp/clipboard';
import {wrapper} from '../../common';
import {usStates} from '../../../core/data';
import {BasicPanelModel} from './BasicPanelModel';
import {wait} from '@xh/hoist/promise';

export const basicPanel = hoistCmp.factory({
model: creates(BasicPanelModel),
Expand Down Expand Up @@ -69,11 +70,27 @@ export const basicPanel = hoistCmp.factory({
})
})
],
contextMenu: [
clipboardMenuItem({
text: 'Copy Text',
getCopyText: () => model.demoText.join('\n')
}),
{
text: 'Increase Text Size',
icon: Icon.plusCircle(),
actionFn: () => model.changeTextSize(true)
},
{
text: 'Decrease Text Size',
icon: Icon.minusCircle(),
actionFn: () => model.changeTextSize(false)
}
],
tbar: [
popover({
position: 'bottom-left',
minimal: true,
target: button({
item: button({
icon: Icon.chevronDown(),
text: 'Menu Button'
}),
Expand Down
8 changes: 8 additions & 0 deletions client-app/src/desktop/tabs/panels/BasicPanelModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@ export class BasicPanelModel extends HoistModel {

'Morbi eget tincidunt ex. Mauris eget egestas nulla. Pellentesque egestas sapien blandit nisi pellentesque varius. Cras dignissim consectetur mauris, eu faucibus quam mattis vel. Curabitur in libero purus. Duis nulla turpis, faucibus sed tristique eget, pretium id nibh. Phasellus sit amet egestas lectus. Donec in aliquet tortor.'
];

changeTextSize(up: boolean) {
const el = document.querySelector('.toolbox-panel-text-reader') as HTMLElement,
fontSize = window.getComputedStyle(el).fontSize,
currentSize = parseFloat(fontSize);

el.style.fontSize = `${currentSize + (up ? 1 : -1)}px`;
}
}
Loading

0 comments on commit b2c8e84

Please sign in to comment.