Skip to content
Merged
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
4 changes: 3 additions & 1 deletion indicator/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@
"valueMaxDecimalPlaces": 1,
"valuePrefix": "",
"valueSuffix": "",
"valueUnitPrefix": true
"valueUnitPrefix": true,
"refreshIntervalValue": 5,
"refreshIntervalUnit": "minutes"
}
9 changes: 7 additions & 2 deletions indicator/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
{
"name": "exb-indicator",
"version": "1.0.1",
"version": "1.0.2",
"description": "A simple indicator widget for Experience Builder, based on the indicator widget from ArcGIS Dashboards.",
"author": "Lucius Creamer",
"license": "MIT",
"keywords": [
"exb-widget",
"experience-builder",
"exb"
]
],
"repository": {
"type": "git",
"url": "git+https://github.com/SunshineLuke90/widgets.git",
"directory": "indicator"
}
}
3 changes: 3 additions & 0 deletions indicator/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export interface Config {

showLastUpdateTime: boolean
lastUpdateTimeTextColor: string

refreshIntervalValue: number
refreshIntervalUnit: "seconds" | "minutes" | "hours"
}

export type IMConfig = ImmutableObject<Config>
5 changes: 2 additions & 3 deletions indicator/src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,7 @@ export function getActiveStyles (

export function relativeTime (date: Date): string {
const diff = Math.floor((Date.now() - date.getTime()) / 1000)
if (diff < 60) return "Updated just now"
if (diff < 60) return `Updated ${diff}s ago`
if (diff < 3600) return `Updated ${Math.floor(diff / 60)}m ago`
if (diff < 86400) return `Updated ${Math.floor(diff / 3600)}h ago`
return `Updated ${date.toLocaleDateString()}`
return `Updated ${Math.floor(diff / 3600)}h ago`
}
27 changes: 27 additions & 0 deletions indicator/src/runtime/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,33 @@ export default function Widget (props: AllWidgetProps<IMConfig>) {
setFeatureIndex((prev) => (prev >= featureCount - 1 ? 0 : prev + 1))
}, [featureCount])

// ── Display tick (re-renders "Last Updated" text every 5 s) ─────────

const [, setTick] = React.useState(0)
React.useEffect(() => {
if (!isConfigured) return
const id = setInterval(() => { setTick((v) => v + 1) }, 5000)
return () => { clearInterval(id) }
}, [isConfigured])

// ── Data refresh on configurable interval ────────────────────────────

const refreshMs = React.useMemo(() => {
const val = config.refreshIntervalValue ?? 5
const unit = config.refreshIntervalUnit ?? "minutes"
const multiplier = unit === "hours" ? 3600000 : unit === "minutes" ? 60000 : 1000
return Math.max(val * multiplier, 1000)
}, [config.refreshIntervalValue, config.refreshIntervalUnit])

React.useEffect(() => {
if (!isConfigured) return
const id = setInterval(() => {
setMainTrigger((v) => v + 1)
setRefTrigger((v) => v + 1)
}, refreshMs)
return () => { clearInterval(id) }
}, [isConfigured, refreshMs])

// ── Main query effect ──────────────────────────────────────────────────

React.useEffect(() => {
Expand Down
43 changes: 43 additions & 0 deletions indicator/src/setting/setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,49 @@ export default function Setting (props: AllWidgetSettingProps<IMConfig>) {
}}
/>
</SettingRow>
<SettingRow
label={props.intl.formatMessage({
id: "refreshInterval",
defaultMessage: "Refresh Interval"
})}
flow={"wrap"}
>
<div style={{ display: "flex", gap: 6, alignItems: "center" }}>
<NumericInput
min={1}
max={9999}
value={config.refreshIntervalValue ?? 5}
style={{ width: 70 }}
onChange={(value) => {
onSettingChange({
id,
config: {
...config,
refreshIntervalValue: value
}
})
}}
/>
<Select
size="sm"
style={{ width: 110 }}
value={config.refreshIntervalUnit ?? "minutes"}
onChange={(e) => {
onSettingChange({
id,
config: {
...config,
refreshIntervalUnit: e.target.value
}
})
}}
>
<option value="seconds">Seconds</option>
<option value="minutes">Minutes</option>
<option value="hours">Hours</option>
</Select>
</div>
</SettingRow>
<SettingRow
label={props.intl.formatMessage({
id: "conditionalFormatting",
Expand Down
Loading