Basic Doctor UI

Summary:
- Basic Doctor UI showing issues with installation
- Run healthchecks in background on startup and show warning message if something is wrong

Reviewed By: jknoxville

Differential Revision: D18502599

fbshipit-source-id: 194939a080ba7412ed3293d95c533bfad7031d3b
This commit is contained in:
Anton Nikolaev
2019-11-21 02:51:35 -08:00
committed by Facebook Github Bot
parent c1de6f4276
commit ddb135ac39
16 changed files with 823 additions and 37 deletions

View File

@@ -20,6 +20,7 @@ export const ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT: 'SELECT_PLUGINS_TO_EXPORT' =
export const ACTIVE_SHEET_SHARE_DATA: 'SHARE_DATA' = 'SHARE_DATA';
export const ACTIVE_SHEET_SIGN_IN: 'SIGN_IN' = 'SIGN_IN';
export const ACTIVE_SHEET_SETTINGS: 'SETTINGS' = 'SETTINGS';
export const ACTIVE_SHEET_DOCTOR: 'DOCTOR' = 'DOCTOR';
export const ACTIVE_SHEET_SHARE_DATA_IN_FILE: 'SHARE_DATA_IN_FILE' =
'SHARE_DATA_IN_FILE';
export const SET_EXPORT_STATUS_MESSAGE: 'SET_EXPORT_STATUS_MESSAGE' =
@@ -33,6 +34,7 @@ export type ActiveSheet =
| typeof ACTIVE_SHEET_SHARE_DATA
| typeof ACTIVE_SHEET_SIGN_IN
| typeof ACTIVE_SHEET_SETTINGS
| typeof ACTIVE_SHEET_DOCTOR
| typeof ACTIVE_SHEET_SHARE_DATA_IN_FILE
| typeof ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT
| null;

View File

@@ -0,0 +1,154 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Actions} from './';
export type State = {
healthcheckReport: HealthcheckReport;
};
export type Action =
| {
type: 'INIT_HEALTHCHECK_REPORT';
payload: HealthcheckReport;
}
| {
type: 'UPDATE_HEALTHCHECK_REPORT_ITEM';
payload: {
categoryIdx: number;
itemIdx: number;
item: HealthcheckReportItem;
};
}
| {
type: 'START_HEALTHCHECKS';
}
| {
type: 'FINISH_HEALTHCHECKS';
};
const INITIAL_STATE: State = {
healthcheckReport: {
isHealthcheckInProgress: false,
categories: [],
},
};
export type HealthcheckStatus =
| 'IN_PROGRESS'
| 'SUCCESS'
| 'FAILED'
| 'WARNING';
export type HealthcheckResult = {
status: HealthcheckStatus;
message?: string;
helpUrl?: string;
};
export type HealthcheckReportItem = {
label: string;
} & HealthcheckResult;
export type HealthcheckReportCategory = {
label: string;
status: HealthcheckStatus;
checks: Array<HealthcheckReportItem>;
};
export type HealthcheckReport = {
isHealthcheckInProgress: boolean;
categories: Array<HealthcheckReportCategory>;
};
export default function reducer(
state: State | undefined = INITIAL_STATE,
action: Actions,
): State {
if (action.type === 'INIT_HEALTHCHECK_REPORT') {
return {
...state,
healthcheckReport: action.payload,
};
} else if (action.type === 'START_HEALTHCHECKS') {
return {
...state,
healthcheckReport: {
...state.healthcheckReport,
isHealthcheckInProgress: true,
},
};
} else if (action.type === 'FINISH_HEALTHCHECKS') {
return {
...state,
healthcheckReport: {
...state.healthcheckReport,
isHealthcheckInProgress: false,
},
};
} else if (action.type === 'UPDATE_HEALTHCHECK_REPORT_ITEM') {
return {
...state,
healthcheckReport: {
...state.healthcheckReport,
categories: [
...state.healthcheckReport.categories.slice(
0,
action.payload.categoryIdx,
),
{
...state.healthcheckReport.categories[action.payload.categoryIdx],
checks: [
...state.healthcheckReport.categories[
action.payload.categoryIdx
].checks.slice(0, action.payload.itemIdx),
{
...action.payload.item,
},
...state.healthcheckReport.categories[
action.payload.categoryIdx
].checks.slice(action.payload.itemIdx + 1),
],
},
...state.healthcheckReport.categories.slice(
action.payload.categoryIdx + 1,
),
],
},
};
} else {
return state;
}
}
export const initHealthcheckReport = (report: HealthcheckReport): Action => ({
type: 'INIT_HEALTHCHECK_REPORT',
payload: report,
});
export const updateHealthcheckReportItem = (
categoryIdx: number,
itemIdx: number,
item: HealthcheckReportItem,
): Action => ({
type: 'UPDATE_HEALTHCHECK_REPORT_ITEM',
payload: {
categoryIdx,
itemIdx,
item,
},
});
export const startHealthchecks = (): Action => ({
type: 'START_HEALTHCHECKS',
});
export const finishHealthchecks = (): Action => ({
type: 'FINISH_HEALTHCHECKS',
});

View File

@@ -40,6 +40,10 @@ import pluginManager, {
State as PluginManagerState,
Action as PluginManagerAction,
} from './pluginManager';
import healthchecks, {
Action as HealthcheckAction,
State as HealthcheckState,
} from './healthchecks';
import user, {State as UserState, Action as UserAction} from './user';
import JsonFileStorage from '../utils/jsonFileReduxPersistStorage';
import os from 'os';
@@ -61,6 +65,7 @@ export type Actions =
| SettingsAction
| SupportFormAction
| PluginManagerAction
| HealthcheckAction
| {type: 'INIT'};
export type State = {
@@ -73,6 +78,7 @@ export type State = {
settingsState: SettingsState & PersistPartial;
supportForm: SupportFormState;
pluginManager: PluginManagerState;
healthchecks: HealthcheckState;
};
export type Store = ReduxStore<State, Actions>;
@@ -124,4 +130,5 @@ export default combineReducers<State, Actions>({
{key: 'settings', storage: settingsStorage},
settings,
),
healthchecks,
});