Skip to content

Commit

Permalink
fix: auto update dashboards on UI load
Browse files Browse the repository at this point in the history
  • Loading branch information
rdubrock committed Oct 15, 2020
1 parent 199aa58 commit a5293a5
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 44 deletions.
62 changes: 55 additions & 7 deletions src/RootPage.tsx
Expand Up @@ -12,6 +12,7 @@ import { TenantSetup } from './components/TenantSetup';
import { InstanceContext } from './components/InstanceContext';
import { ChecksPage } from 'page/ChecksPage';
import { ProbesPage } from 'page/ProbesPage';
import { importDashboard, listAppDashboards } from 'dashboards/loader';

interface Props extends AppRootProps<GlobalSettings> {}
interface State {
Expand All @@ -20,6 +21,8 @@ interface State {
loadingInstance: boolean;
info?: RegistrationInfo;
valid?: boolean;
checkingForDashboardChanges: boolean;
dashboardsNeedUpdate?: boolean;
}

export class RootPage extends PureComponent<Props, State> {
Expand All @@ -29,6 +32,7 @@ export class RootPage extends PureComponent<Props, State> {
this.state = {
settings: findSMDataSources(),
loadingInstance: true,
checkingForDashboardChanges: true,
};
}

Expand All @@ -44,12 +48,14 @@ export class RootPage extends PureComponent<Props, State> {
logs: await loadDataSourceIfExists(global?.logs?.grafanaName),
};

this.setState({
instance,
loadingInstance: false,
valid: isValid(instance),
});
this.updateNav();
this.setState(
{
instance,
loadingInstance: false,
valid: isValid(instance),
},
this.updateDashboards
);
return;
}
}
Expand All @@ -65,7 +71,7 @@ export class RootPage extends PureComponent<Props, State> {

async componentDidMount() {
this.updateNav();
this.loadInstances();
await this.loadInstances();
}

componentDidUpdate(prevProps: Props) {
Expand All @@ -76,6 +82,47 @@ export class RootPage extends PureComponent<Props, State> {
}
}

async updateDashboards() {
const { instance } = this.state;
const latestDashboards = await listAppDashboards();
const existingDashboards = instance?.api.instanceSettings.jsonData.dashboards ?? [];

const dashboardsNeedingUpdate = existingDashboards
.map(existingDashboard => {
const templateDashboard = latestDashboards.find(template => template.uid === existingDashboard.uid);
const templateVersion = templateDashboard?.latestVersion ?? -1;
if (templateDashboard && templateVersion > existingDashboard.version) {
return {
...existingDashboard,
version: templateDashboard.latestVersion,
latestVersion: templateDashboard.latestVersion,
};
}
return null;
})
.filter(Boolean);

if (dashboardsNeedingUpdate.length) {
// import the new version of the dashboards into Grafana
const updatedDashboards = await Promise.all(
dashboardsNeedingUpdate.map(
dashboard => dashboard && importDashboard(dashboard?.json, instance?.api.instanceSettings.jsonData!)
)
);

// store the latest dashboard versions in the SM datasource
const mergedDashboards = existingDashboards.map(
dashboard => updatedDashboards.find(updatedDashboard => updatedDashboard?.uid === dashboard.uid) ?? dashboard
);
instance?.api.onOptionsChange({
...instance.api.instanceSettings.jsonData,
dashboards: mergedDashboards,
});

this.updateNav();
}
}

updateNav() {
const { path, onNavChanged, query, meta } = this.props;
const selected = query.page || 'checks';
Expand Down Expand Up @@ -189,6 +236,7 @@ export class RootPage extends PureComponent<Props, State> {

renderPage() {
const { settings, valid, instance } = this.state;

if (settings.length > 1) {
return this.renderMultipleConfigs();
}
Expand Down
61 changes: 24 additions & 37 deletions src/components/DashboardList.tsx
Expand Up @@ -19,60 +19,47 @@ export class DashboardList extends PureComponent<Props, State> {
};

async componentDidMount() {
const { checkUpdates, onChange } = this.props;
const { checkUpdates, onChange, options } = this.props;
if (!checkUpdates || !onChange) {
return;
}
const latestDashboards = await listAppDashboards();

// merge dashboards known to grafana with latest in the app.
let dashboards = [...this.state.dashboards];
const latestDashboards = await listAppDashboards();
for (const dashboard of latestDashboards) {
let i = dashboards.findIndex(item => {
return item.uid === dashboard.uid;
});
if (i < 0) {
dashboards.push(dashboard);
} else {
dashboards[i].latestVersion = dashboard.latestVersion;
if (!dashboards[i].version) {
dashboards[i].version = -1;
}
const dashboards = latestDashboards.map(template => {
const existingDashboard = options.dashboards.find(existing => template.uid === existing.uid);
if (!existingDashboard) {
return template;
}
}
console.log(dashboards);
return {
...existingDashboard,
latestVersion: template.latestVersion,
};
});

this.setState({ dashboards });
}

onImport = (dashboard: DashboardInfo) => async () => {
const { onChange } = this.props;
const { onChange, options } = this.props;
if (!onChange) {
return;
}
let options = { ...this.props.options };
const updated = await importDashboard(dashboard.json, options);
console.log('dashboard updated');
let i = options.dashboards.findIndex(item => {
return item.uid === updated.uid;
});
if (i < 0) {
options.dashboards.push(updated);
} else {
options.dashboards[i] = updated;
}
const updatedDashboard = await importDashboard(dashboard.json, options);

let dashboards = [...this.state.dashboards];
i = dashboards.findIndex(item => {
return item.uid === updated.uid;
const dashboards = options.dashboards.map(savedDashboard => {
if (savedDashboard.uid === updatedDashboard.uid) {
return updatedDashboard;
}
return savedDashboard;
});
if (i < 0) {
dashboards.push(updated);
} else {
dashboards[i] = updated;
}

const updatedOptions = {
...options,
dashboards,
};
this.setState({ dashboards });
return onChange(options);
return onChange(updatedOptions);
};

onRemove = (dashboard: DashboardInfo) => async () => {
Expand Down

0 comments on commit a5293a5

Please sign in to comment.