-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:Esri/arcgis-experience-builder-sd…
…k-resources
- Loading branch information
Showing
77 changed files
with
2,041 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,26 @@ | ||
## Samples | ||
|
||
* [Add layers](add-layers) | ||
* [Client-side output data source](client-side-output) | ||
* [Create a data source using a feature layer (class)](feature-layer-class) | ||
* [Create a data source using a feature layer (function)](feature-layer-function) | ||
* [Creating a class component/widget](demo) | ||
* [Creating a functional component/widget](demo-function) | ||
* [Display a webmap as a data source](map-view) | ||
* [Legend widget](js-api-widget) | ||
* [Show extent with a map view](showextent) | ||
* [Create a data source using a feature layer (class)](feature-layer-class) | ||
* [Create a data source using a feature layer (function)](feature-layer-function) | ||
* [Editor widget](editor) | ||
* [Get map coordinates (class)](get-map-coordinates-class) | ||
* [Get map coordinates (function)](get-map-coordinates-function) | ||
* [Legend widget](js-api-widget) | ||
* [Message action](message-subscriber) | ||
* [Point clustering](clustering) | ||
* [Server-side output data source](server-side-output) | ||
* [Share state between widgets](redux) | ||
* [Show a record id](show-record-id) | ||
* [Show extent with a map view](showextent) | ||
* [Using a D3 library](d3) | ||
* [Using a jQuery library](jquery) | ||
* [Using a react data grid library](react-data-grid) | ||
* [Share state between widgets](redux) | ||
* [Using statistics to create an output data source](statistic-client-side-output) | ||
* [View layers toggle](view-layers-toggle) | ||
* [Web component](web-component) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Client-side output data source | ||
|
||
An output data source can save data in a data source instance, this is called a client-side output data source. | ||
|
||
## How to use the sample | ||
|
||
Clone the [sample repo](https://github.com/esri/arcgis-experience-builder-sdk-resources) and copy this widget's folder (within `samples/widgets`) to the `client/your-extensions/widgets` folder of your Experience Builder installation. | ||
|
||
## How it works | ||
|
||
In `setting.tsx`, use `DataSourceSelector` to allow the user to select an origin data source. Declare the output data source inside `onChange` callback of `DataSourceSelector`. | ||
|
||
```ts | ||
// Let framework know which data source current widget is using and which data source current widget is the output. | ||
this.props.onSettingChange({ | ||
id: this.props.id, | ||
useDataSources: useDataSources | ||
}, outputDsJsons) | ||
``` | ||
|
||
Select a filter and save it in widget config. | ||
|
||
```tsx | ||
<SqlExpressionBuilderPopup | ||
dataSource={ds} | ||
mode={SqlExpressionMode.Simple} | ||
expression={this.props.config.sqlExpression} | ||
// use this.props.onSettingChange to save filter to config inside this callback | ||
onChange={this.onSqlExpressionChange} | ||
isOpen={this.state.isSqlBuilderOpen} | ||
toggle={this.toggleSqlBuilder} | ||
/> | ||
``` | ||
|
||
In `widget.tsx`, use `DataSourceComponent` to create origin data source instance. Update the output data source's source records every time the user clicks the `update output data source` button. | ||
|
||
```tsx | ||
<Button onClick={this.setSourceRecordsToOutputDs}> | ||
Update output data source | ||
</Button> | ||
``` | ||
|
||
Please note this widget only generates an output data source. If you want to use the output data source, please add another widget (such as the List widget) and select the output data source for it. This sample widget does not listen to the origin data source change, you can use `onDataSourceInfoChange` callback of the `DataSourceComponent` to listen to the origin data source change. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
{ | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "client-side-output", | ||
"type": "widget", | ||
"version": "1.4.0", | ||
"exbVersion": "1.4.0", | ||
"author": "Esri R&D Center Beijing", | ||
"description": "This is the widget used in developer guide", | ||
"copyright": "", | ||
"license": "http://www.apache.org/licenses/LICENSE-2.0", | ||
"defaultSize": { | ||
"width": 400, | ||
"height": 400 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { ImmutableObject, IMSqlExpression } from 'jimu-core' | ||
|
||
export interface Config { | ||
sqlExpression?: IMSqlExpression | ||
} | ||
|
||
export type IMConfig = ImmutableObject<Config> |
105 changes: 105 additions & 0 deletions
105
samples/widgets/client-side-output/src/runtime/widget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { React, AllWidgetProps, DataSourceComponent, dataSourceUtils, DataSourceManager, FeatureLayerDataSource, DataSourceStatus } from 'jimu-core' | ||
import { Button } from 'jimu-ui' | ||
|
||
import { IMConfig } from '../config' | ||
|
||
export default class Widget extends React.PureComponent<AllWidgetProps<IMConfig>, unknown> { | ||
isDsConfigured = () => { | ||
if (this.props.useDataSources && this.props.useDataSources.length === 1) { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
onDataSourceCreated = () => { | ||
this.setSourceRecordsToOutputDs() | ||
} | ||
|
||
onCreateDataSourceFailed = () => { | ||
this.setSourceRecordsToOutputDs() | ||
} | ||
|
||
getOriginDataSource = () => { | ||
return DataSourceManager.getInstance().getDataSource(this.props.useDataSources?.[0]?.dataSourceId) | ||
} | ||
|
||
getOutputDataSource = () => { | ||
return DataSourceManager.getInstance().getDataSource(this.props.outputDataSources?.[0]) | ||
} | ||
|
||
setSourceRecordsToOutputDs = () => { | ||
/** | ||
* Just like using other data sources, to use an output data source, widget should use it through `DataSourceComponent`, the framework will create the data source instance on the fly. | ||
* No output data source instance means there isn't any widgets using the output data source, | ||
* in this case, no need to set source to the output data source. | ||
*/ | ||
if (!this.getOutputDataSource()) { | ||
return | ||
} | ||
|
||
/** | ||
* Need origin data source instance to get source records. | ||
* If do not have origin data source instance, set status of output data source to not ready, which indicates output data source is not ready to do query. | ||
*/ | ||
if (!this.getOriginDataSource()) { | ||
this.getOutputDataSource().setStatus(DataSourceStatus.NotReady) | ||
this.getOutputDataSource().setCountStatus(DataSourceStatus.NotReady) | ||
return | ||
} | ||
|
||
const sql = dataSourceUtils.getArcGISSQL(this.props.config.sqlExpression, this.getOriginDataSource()).sql || '1=1' | ||
const featureLayerDs = this.getOriginDataSource() as FeatureLayerDataSource | ||
featureLayerDs.query({ where: sql }).then(res => { | ||
/** | ||
* Set source to the output data source. | ||
* Output data source can use the source to do query, to load records and so on. | ||
* If use the source to load records, | ||
* will save the loaded records to output data source instance and widget can get these records by `outputDs.getRecords()`. | ||
*/ | ||
this.getOutputDataSource()?.setSourceRecords(res.records) | ||
/** | ||
* Status of output data source is not ready by default, set it to unloaded to let other widgets know output data source is ready to do query. | ||
*/ | ||
this.getOutputDataSource()?.setStatus(DataSourceStatus.Unloaded) | ||
this.getOutputDataSource()?.setCountStatus(DataSourceStatus.Unloaded) | ||
}) | ||
} | ||
|
||
render () { | ||
if (!this.isDsConfigured()) { | ||
return ( | ||
<h3> | ||
This widget demonstrates how to use attribute query results to generate a client-side output data source. | ||
<br /> | ||
Please config data source. | ||
</h3> | ||
) | ||
} | ||
|
||
return ( | ||
<div className='widget-attribute-query-result-as-output' style={{ width: '100%', height: '100%', maxHeight: '800px', overflow: 'auto' }}> | ||
<h3> | ||
The client-side output data source is generated. | ||
</h3> | ||
<h5> | ||
If you want to use the client-side output data source, you should add another widget (such as List) and configure the output data source for it. | ||
</h5> | ||
<h5> | ||
If the widget's origin data source is changed (e.g. add a filter), the output data source won't update automatically. Please click the following button. | ||
</h5> | ||
|
||
<Button onClick={this.setSourceRecordsToOutputDs}> | ||
Update output data source | ||
</Button> | ||
|
||
<DataSourceComponent | ||
useDataSource={this.props.useDataSources[0]} | ||
widgetId={this.props.id} | ||
onDataSourceCreated={this.onDataSourceCreated} | ||
onCreateDataSourceFailed={this.onCreateDataSourceFailed} | ||
/> | ||
|
||
</div> | ||
) | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
samples/widgets/client-side-output/src/setting/setting.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { React, Immutable, DataSourceTypes, DataSourceManager, UseDataSource, DataSourceJson, SqlExpressionMode, IMSqlExpression } from 'jimu-core' | ||
import { AllWidgetSettingProps } from 'jimu-for-builder' | ||
import { SqlExpressionBuilderPopup } from 'jimu-ui/advanced/sql-expression-builder' | ||
import { getJimuFieldNamesBySqlExpression } from 'jimu-ui/basic/sql-expression-runtime' | ||
import { DataSourceSelector } from 'jimu-ui/advanced/data-source-selector' | ||
import { IMConfig } from '../config' | ||
import { Button } from 'jimu-ui' | ||
|
||
interface State { | ||
isSqlBuilderOpen: boolean | ||
} | ||
|
||
export default class Setting extends React.PureComponent<AllWidgetSettingProps<IMConfig>, State> { | ||
supportedTypes = Immutable([DataSourceTypes.FeatureLayer]) | ||
|
||
constructor (props) { | ||
super(props) | ||
this.state = { | ||
isSqlBuilderOpen: false | ||
} | ||
} | ||
|
||
onDataSourceChange = (useDataSources: UseDataSource[]) => { | ||
if (useDataSources?.length > 0) { | ||
const originDsId = useDataSources[0]?.dataSourceId | ||
const originDs = DataSourceManager.getInstance().getDataSource(originDsId) | ||
const outputDsJsons: DataSourceJson[] = [{ | ||
id: `${this.props.id}-ouput`, | ||
type: DataSourceTypes.FeatureLayer, | ||
label: `${this.props.manifest.name}-output-data-source`, | ||
geometryType: originDs.getDataSourceJson().geometryType, | ||
originDataSources: [useDataSources[0]], | ||
isDataInDataSourceInstance: true | ||
}] | ||
|
||
// Let framework know which data source current widget is using and which data source current widget is outputing. | ||
this.props.onSettingChange({ | ||
id: this.props.id, | ||
useDataSources: useDataSources | ||
}, outputDsJsons) | ||
} | ||
} | ||
|
||
onSqlExpressionChange = (sqlExpression: IMSqlExpression) => { | ||
const usedFields = getJimuFieldNamesBySqlExpression(sqlExpression) | ||
const newUseDs = this.props.useDataSources[0].set('fields', usedFields).asMutable({ deep: true }) | ||
|
||
// Save the SQL expression to config and update use data sources based on the fields SQL expression is using. | ||
this.props.onSettingChange({ | ||
id: this.props.id, | ||
useDataSources: [newUseDs], | ||
config: { sqlExpression } | ||
}) | ||
} | ||
|
||
toggleSqlBuilder = () => this.setState({ isSqlBuilderOpen: !this.state.isSqlBuilderOpen }) | ||
|
||
render () { | ||
const dsId = this.props.useDataSources?.[0]?.dataSourceId | ||
const ds = dsId && DataSourceManager.getInstance().getDataSource(dsId) | ||
return ( | ||
<div className='setting-attribute-query-result-as-output p-2'> | ||
<DataSourceSelector | ||
mustUseDataSource | ||
types={this.supportedTypes} | ||
useDataSources={this.props.useDataSources} | ||
useDataSourcesEnabled={this.props.useDataSourcesEnabled} | ||
onChange={this.onDataSourceChange} | ||
widgetId={this.props.id} | ||
/> | ||
|
||
{ | ||
ds && <div className='mt-2'> | ||
<Button onClick={this.toggleSqlBuilder}>Click to set a SQL expression</Button> | ||
</div> | ||
} | ||
|
||
<SqlExpressionBuilderPopup | ||
dataSource={ds} | ||
mode={SqlExpressionMode.Simple} | ||
expression={this.props.config.sqlExpression} | ||
onChange={this.onSqlExpressionChange} | ||
isOpen={this.state.isSqlBuilderOpen} | ||
toggle={this.toggleSqlBuilder} | ||
/> | ||
</div> | ||
) | ||
} | ||
} |
Oops, something went wrong.