Data caching updates
This commit is contained in:
Родитель
cf7f094841
Коммит
b59f3c8b0f
|
@ -45,37 +45,25 @@ function getAccessTokenForScope(silentFail: boolean, msalInstance: any, scope: a
|
|||
});
|
||||
}
|
||||
|
||||
function getCentralApplicationsARM(accessToken: string, subscriptionId: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
axios.get(`https://management.azure.com/subscriptions/${subscriptionId}/providers/Microsoft.IoTCentral/IoTApps?api-version=2018-09-01`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + accessToken
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res.data.value);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getCentralTemplates(apps: Array<any>, accessToken: string) {
|
||||
function getCentralData(apps: Array<any>, accessToken: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const templatesMap = {};
|
||||
const validTemplates: Array<string> = [];
|
||||
const validApps: Array<any> = [];
|
||||
for (const appIndex in apps) {
|
||||
const appId = apps[appIndex];
|
||||
const res: any = await axios.get(`https://${appId}${Config.AppDNS}/api/preview/deviceTemplates`, { headers: { Authorization: 'Bearer ' + accessToken } })
|
||||
for (const templateIndex in res.data.value) {
|
||||
if (res.data.value[templateIndex].displayName === Config.template) {
|
||||
validApps.push(appId);
|
||||
validTemplates.push(res.data.value[templateIndex].id)
|
||||
templatesMap[appId] = res.data.value[templateIndex].id;
|
||||
break;
|
||||
const appId = apps[appIndex].properties.applicationId;
|
||||
try {
|
||||
const res: any = await axios.get(`https://${appId}${Config.AppDNS}/api/preview/deviceTemplates`, { headers: { Authorization: 'Bearer ' + accessToken } })
|
||||
for (const templateIndex in res.data.value) {
|
||||
if (res.data.value[templateIndex].displayName === Config.template) {
|
||||
validApps.push(appId);
|
||||
validTemplates.push(res.data.value[templateIndex].id)
|
||||
templatesMap[appId] = res.data.value[templateIndex].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("Skipping app: " + appId);
|
||||
}
|
||||
}
|
||||
if (validTemplates.length > 0) {
|
||||
|
@ -102,6 +90,22 @@ function getSubscriptionsARM(accessToken: string) {
|
|||
});
|
||||
}
|
||||
|
||||
function getCentralApplicationsARM(accessToken: string, subscriptionId: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
axios.get(`https://management.azure.com/subscriptions/${subscriptionId}/providers/Microsoft.IoTCentral/IoTApps?api-version=2018-09-01`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + accessToken
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res.data.value);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getTenantsARM(accessToken: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
axios.get(`https://management.azure.com/tenants?api-version=2020-01-01`, {
|
||||
|
@ -202,46 +206,30 @@ export class AuthProvider extends React.PureComponent {
|
|||
|
||||
selectSubscription = async (subscription: any) => {
|
||||
|
||||
let cachedApps, cachedFilter = null;
|
||||
let cachedApps, cachedFilter: any = null;
|
||||
try {
|
||||
cachedApps = JSON.parse(localStorage.getItem('cachedState') as string);
|
||||
cachedFilter = JSON.parse(localStorage.getItem('cachedFilter') as string);
|
||||
cachedApps = localStorage.getItem('cachedState');
|
||||
cachedFilter = localStorage.getItem('cachedFilter');
|
||||
} catch { };
|
||||
|
||||
if (Config.cacheAppDevices) {
|
||||
if (cachedApps) {
|
||||
if (Config.cacheAppFilters && cachedFilter) { cachedApps.filteredApps = cachedFilter; }
|
||||
this.setState(cachedApps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let filtered: Array<string> = [];
|
||||
if (Config.cacheAppFilters && cachedFilter) {
|
||||
filtered = cachedFilter;
|
||||
}
|
||||
else {
|
||||
for (const app in subscription.apps) {
|
||||
filtered.push(subscription.apps[app].properties.applicationId);
|
||||
}
|
||||
if (Config.cacheApps && cachedApps !== null && cachedApps !== '') {
|
||||
const newState: any = JSON.parse(cachedApps);
|
||||
if (cachedFilter !== null && cachedFilter !== '') { newState.filteredApps = JSON.parse(cachedFilter) }
|
||||
this.setState(newState);
|
||||
return;
|
||||
}
|
||||
|
||||
const apps = Object.assign({}, subscription.apps);
|
||||
const centralToken: any = await getAccessTokenForScope(true, this.msalInstance, Scopes.Central, { account: this.state.loginAccount });
|
||||
const templates: any = await getCentralTemplates(filtered, centralToken.accessToken)
|
||||
|
||||
const newApps: any = [];
|
||||
for (const app of subscription.apps) {
|
||||
if (templates.validApps.indexOf(app.properties.applicationId) > -1) { newApps.push(app); }
|
||||
}
|
||||
|
||||
subscription.apps = newApps;
|
||||
const central: any = await getCentralData(apps, centralToken.accessToken)
|
||||
|
||||
const state = {
|
||||
subscription: true,
|
||||
activeSubscription: subscription,
|
||||
filteredApps: filtered,
|
||||
filteredAppsTemplates: templates.templatesMap,
|
||||
validTemplates: templates.validTemplates
|
||||
centralApps: central.validApps,
|
||||
filteredApps: Config.cacheApps && cachedFilter !== null && cachedFilter !== '' ? JSON.parse(cachedFilter) : central.validApps,
|
||||
filteredAppsTemplates: central.templatesMap,
|
||||
validTemplates: central.validTemplates
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
|
@ -282,6 +270,7 @@ export class AuthProvider extends React.PureComponent {
|
|||
return res.accessToken;
|
||||
}
|
||||
|
||||
// This list is contains the full list of apps per subscription
|
||||
getSubscriptionSelectorList = async () => {
|
||||
const subs: Array<any> = [];
|
||||
if (this.state.authenticated) {
|
||||
|
@ -291,12 +280,12 @@ export class AuthProvider extends React.PureComponent {
|
|||
}
|
||||
|
||||
for (const i in this.state.loginSubscriptions) {
|
||||
const sub = this.state.loginSubscriptions[i];
|
||||
const directory = directories[sub.tenantId];
|
||||
const armToken: any = await getAccessTokenForScope(true, this.msalInstance, Scopes.ARM, { account: this.state.loginAccount });
|
||||
const subscription = this.state.loginSubscriptions[i];
|
||||
const directory = directories[subscription.tenantId];
|
||||
try {
|
||||
const apps = await getCentralApplicationsARM(armToken.accessToken, sub.subscriptionId);
|
||||
subs.push({ directory, subscription: sub, apps });
|
||||
const armToken: any = await getAccessTokenForScope(true, this.msalInstance, Scopes.ARM, { account: this.state.loginAccount });
|
||||
const apps = await getCentralApplicationsARM(armToken.accessToken, subscription.subscriptionId);
|
||||
subs.push({ directory, subscription, apps });
|
||||
} catch { console.log('no perms') }
|
||||
};
|
||||
}
|
||||
|
@ -310,6 +299,7 @@ export class AuthProvider extends React.PureComponent {
|
|||
state: any = {
|
||||
authenticated: false,
|
||||
subscription: false,
|
||||
centralApps: [],
|
||||
filteredApps: [],
|
||||
filteredAppsTemplates: {},
|
||||
loginAccount: {},
|
||||
|
|
|
@ -26,25 +26,25 @@ function makeAPICall(api, accessToken: string) {
|
|||
});
|
||||
}
|
||||
|
||||
async function getDevicesForApps(appHosts: Array<string>, domain: string, token: string) {
|
||||
async function getDevicesForApps(apps: Array<string>, domain: string, token: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const appDevices = {};
|
||||
try {
|
||||
for (const host in appHosts) {
|
||||
const res: any = await makeAPICall(`https://${appHosts[host]}${domain}/api/preview/devices`, token)
|
||||
appDevices[appHosts[host]] = res.data.value;
|
||||
for (const appId in apps) {
|
||||
const res: any = await makeAPICall(`https://${apps[appId]}${domain}/api/preview/devices`, token)
|
||||
appDevices[apps[appId]] = res.data.value;
|
||||
}
|
||||
resolve(appDevices);
|
||||
} catch (err) { console.warn(err); reject(err); }
|
||||
})
|
||||
}
|
||||
|
||||
async function getDeviceProperty(appHost: string, domain: string, deviceId: string, token: string) {
|
||||
async function getDeviceProperty(appId: string, domain: string, deviceId: string, token: string) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let res1, res2: any = null;
|
||||
try {
|
||||
res1 = await makeAPICall(`https://${appHost}${domain}/api/preview/devices/${deviceId}/properties`, token)
|
||||
res2 = await makeAPICall(`https://${appHost}${domain}/api/preview/devices/${deviceId}/cloudProperties`, token)
|
||||
res1 = await makeAPICall(`https://${appId}${domain}/api/preview/devices/${deviceId}/properties`, token)
|
||||
res2 = await makeAPICall(`https://${appId}${domain}/api/preview/devices/${deviceId}/cloudProperties`, token)
|
||||
resolve(Object.assign({}, res1.data || {}, res2.data || {}));
|
||||
} catch (err) { console.warn(err); reject(err); }
|
||||
})
|
||||
|
@ -60,9 +60,7 @@ async function getMapData(token: string, templates: any, appDevices: Array<any>,
|
|||
|
||||
console.log('Map fetch:' + new Date(Date.now()));
|
||||
|
||||
for (const appId in appDevices) {
|
||||
if (filteredApps.indexOf(appId) === -1) { continue; }
|
||||
|
||||
for (const appId of filteredApps) {
|
||||
const devices = appDevices[appId];
|
||||
for (const device in devices) {
|
||||
if (validTemplates.indexOf(devices[device]['instanceOf']) > -1) {
|
||||
|
@ -118,33 +116,39 @@ export class DataProvider extends React.PureComponent {
|
|||
this.startMapData(getToken, templates, filteredApps);
|
||||
}
|
||||
|
||||
getDevices = async (appHosts: Array<string>, token: string, filteredApps: Array<string>, overrideCache: boolean) => {
|
||||
getDevices = async (apps: Array<string>, token: string, overrideCache: boolean) => {
|
||||
// ONLY THIS METHOD SHOULD UPDATE THE devices STATE PROPERTY
|
||||
let devices: any = null;
|
||||
if (!overrideCache && Config.cacheAppDevices) {
|
||||
let cachedDevices: any = null;
|
||||
if (!overrideCache && Config.cacheDevices) {
|
||||
try {
|
||||
devices = JSON.parse(localStorage.getItem('cachedDevices') as string);
|
||||
cachedDevices = localStorage.getItem('cachedDevices');
|
||||
} catch { };
|
||||
}
|
||||
|
||||
if (!devices || devices === '') {
|
||||
devices = await getDevicesForApps(appHosts, Config.AppDNS, token);
|
||||
localStorage.setItem('cachedDevices', JSON.stringify(devices));
|
||||
}
|
||||
|
||||
this.setState({ devices });
|
||||
|
||||
for (const appId in this.state.devices) {
|
||||
if (filteredApps.indexOf(appId) === -1) { continue; }
|
||||
const propDevices: any = this.state.devices[appId];
|
||||
const length = propDevices.length;
|
||||
const newState = Object.assign({}, this.state.devices);
|
||||
for (let i = 0; i < length; i++) {
|
||||
const props = await getDeviceProperty(appId, Config.AppDNS, propDevices[i].id, token);
|
||||
newState[appId][i]['__properties'] = props;
|
||||
}
|
||||
if (!overrideCache && Config.cacheDevices && cachedDevices !== null && cachedDevices !== '') {
|
||||
const newState: any = JSON.parse(cachedDevices);
|
||||
this.setState({ devices: newState });
|
||||
return;
|
||||
}
|
||||
|
||||
const devices: any = await getDevicesForApps(apps, Config.AppDNS, token);
|
||||
|
||||
setTimeout(async () => {
|
||||
for (const appId in devices) {
|
||||
const newState = Object.assign({}, this.state.devices);
|
||||
const propDevices: any = newState[appId];
|
||||
const length = propDevices.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const props = await getDeviceProperty(appId, Config.AppDNS, propDevices[i].id, token);
|
||||
newState[appId][i]['__properties'] = props;
|
||||
}
|
||||
localStorage.setItem('cachedDevices', JSON.stringify(newState));
|
||||
this.setState({ devices: newState });
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
// fetch the list of devices first
|
||||
this.setState({ devices });
|
||||
}
|
||||
|
||||
sendCommand = async (host: string, id: string, name: string, body: any, token: string) => {
|
||||
|
|
|
@ -18,7 +18,7 @@ const useDevices = (override: boolean) => {
|
|||
setError(null);
|
||||
try {
|
||||
const token = await authContext.getCentralAccessToken();
|
||||
await dataContext.getDevices(authContext.filteredApps, token, authContext.filteredApps, override);
|
||||
await dataContext.getDevices(authContext.centralApps, token, override);
|
||||
setData({});
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
|
|
|
@ -6,6 +6,7 @@ export default function AppBar({ authContext }) {
|
|||
const dom: any = [];
|
||||
for (let i in authContext.activeSubscription.apps) {
|
||||
const app = authContext.activeSubscription.apps[i];
|
||||
if (authContext.centralApps.indexOf(app.properties.applicationId) === -1) { continue; }
|
||||
const checked = authContext.filteredApps.indexOf(app.properties.applicationId) > -1;
|
||||
dom.push(<div key={app.name} className='app'>
|
||||
<div>{app.properties.displayName}</div>
|
||||
|
|
Загрузка…
Ссылка в новой задаче