[STABLE][TEST-ME] Draft I

pull/1274/head
Rick Carlino 2019-07-15 14:44:40 -05:00
parent 51d8f0e0ca
commit 6fef439d20
10 changed files with 87 additions and 17 deletions

View File

@ -28,7 +28,7 @@ import { t } from "./i18next_wrapper";
import { ResourceIndex } from "./resources/interfaces";
import { isBotOnline } from "./devices/must_be_online";
import { getStatus } from "./connectivity/reducer_support";
import { getAlerts } from "./messages/state_to_props";
import { getApiAlerts } from "./messages/state_to_props";
/** For the logger module */
init();
@ -75,7 +75,7 @@ export function mapStateToProps(props: Everything): AppProps {
tour: props.resources.consumers.help.currentTour,
resources: props.resources.index,
autoSync: !!(fbosConfig && fbosConfig.auto_sync),
alertCount: getAlerts(props.resources.index).length,
alertCount: getApiAlerts(props.resources.index).length,
};
}
/** Time at which the app gives up and asks the user to refresh */

View File

@ -18,7 +18,7 @@ import {
} from "../farmware/state_to_props";
import { getFbosConfig, getFirmwareConfig } from "../resources/getters";
import { DevSettings } from "../account/dev/dev_support";
import { getAlerts } from "../messages/state_to_props";
import { getApiAlerts, getLocalAlerts } from "../messages/state_to_props";
export function mapStateToProps(props: Everything): Props {
const { hardware } = props.bot;
@ -50,6 +50,9 @@ export function mapStateToProps(props: Everything): Props {
env,
saveFarmwareEnv: saveOrEditFarmwareEnv(props.resources.index),
timeSettings: maybeGetTimeSettings(props.resources.index),
alerts: getAlerts(props.resources.index),
alerts: [
...getLocalAlerts(props.resources.consumers.alerts),
...getApiAlerts(props.resources.index)
],
};
}

View File

@ -6,7 +6,7 @@ import {
CommonAlertCardProps,
DismissAlertProps,
Bulletin,
BulletinAlertState
AlertComponentState
} from "./interfaces";
import { formatLogTime } from "../logs";
import {
@ -83,8 +83,8 @@ const ICON_LOOKUP: { [x: string]: string } = {
};
class BulletinAlert
extends React.Component<CommonAlertCardProps, BulletinAlertState> {
state: BulletinAlertState = { bulletin: undefined, no_content: false };
extends React.Component<CommonAlertCardProps, AlertComponentState> {
state: AlertComponentState = { bulletin: undefined, no_content: false };
componentDidMount() {
fetchBulletinContent(this.props.alert.slug)

View File

@ -1,4 +1,4 @@
import { FirmwareHardware, Alert } from "farmbot";
import { FirmwareHardware, Alert, Dictionary } from "farmbot";
import { TimeSettings } from "../interfaces";
import { UUID } from "../resources/interfaces";
@ -89,7 +89,11 @@ export interface Bulletin {
title: string | undefined;
}
export interface BulletinAlertState {
export interface AlertComponentState {
bulletin: Bulletin | undefined;
no_content: boolean;
}
export interface AlertReducerState {
alerts: Dictionary<Alert | undefined>;
}

View File

@ -0,0 +1,51 @@
import { AlertReducerState as State } from "./interfaces";
import { generateReducer } from "../redux/generate_reducer";
import { SyncBodyContents } from "../sync/actions";
import { TaggedResource } from "farmbot";
import { Actions } from "../constants";
import { ReduxAction } from "../redux/interfaces";
type Reducer =
(state: State, fn: ReduxAction<TaggedResource>) => State;
const DEFAULT: Reducer =
(s, a) => handleFbosConf(s, a.payload);
const FIRMWARE_MISSING =
"farmbot_os.firmware.missing";
export const initialState: State = { alerts: {} };
const handleFbosConf =
(s: State, resource: TaggedResource): State => {
if (resource.kind === "FbosConfig") {
if (resource.body.firmware_hardware) {
delete s.alerts[FIRMWARE_MISSING];
} else {
s.alerts[FIRMWARE_MISSING] = {
created_at: 1,
problem_tag: FIRMWARE_MISSING,
priority: 99999,
slug: "firmware-missing",
};
}
}
return s;
};
const pickConfigs = (x: TaggedResource) => x.kind === "FbosConfig";
export const alertsReducer =
generateReducer<State>(initialState)
.add<SyncBodyContents<TaggedResource>>(Actions.RESOURCE_READY, (s, a) => {
const conf = a.payload.body.filter(pickConfigs)[0];
return (conf) ? handleFbosConf(s, conf) : s;
})
.add<TaggedResource[]>(Actions.BATCH_INIT, (s, a) => {
const conf = a.payload.filter(pickConfigs)[0];
return conf ? handleFbosConf(s, conf) : s;
})
.add<TaggedResource>(Actions.REFRESH_RESOURCE_OK, DEFAULT)
.add<TaggedResource>(Actions.SAVE_RESOURCE_OK, DEFAULT)
.add<TaggedResource>(Actions.SAVE_RESOURCE_START, DEFAULT);

View File

@ -1,6 +1,6 @@
import { Everything } from "../interfaces";
import { MessagesProps } from "./interfaces";
import { validFbosConfig } from "../util";
import { MessagesProps, AlertReducerState } from "./interfaces";
import { validFbosConfig, betterCompact } from "../util";
import { getFbosConfig } from "../resources/getters";
import { sourceFbosConfigValue } from "../devices/components/source_config_value";
import {
@ -19,7 +19,10 @@ export const mapStateToProps = (props: Everything): MessagesProps => {
const findApiAlertById = (id: number): UUID =>
findResourceById(props.resources.index, "Alert", id);
return {
alerts: getAlerts(props.resources.index),
alerts: [
...getLocalAlerts(props.resources.consumers.alerts),
...getApiAlerts(props.resources.index)
],
apiFirmwareValue: isFwHardwareValue(apiFirmwareValue)
? apiFirmwareValue : undefined,
timeSettings: maybeGetTimeSettings(props.resources.index),
@ -28,6 +31,8 @@ export const mapStateToProps = (props: Everything): MessagesProps => {
};
};
export const getAlerts = (resourceIndex: ResourceIndex): Alert[] => {
return selectAllAlerts(resourceIndex).map(x => x.body);
};
export const getApiAlerts = (resourceIndex: ResourceIndex): Alert[] =>
selectAllAlerts(resourceIndex).map(x => x.body);
export const getLocalAlerts = ({ alerts }: AlertReducerState) =>
betterCompact(Object.values(alerts));

View File

@ -5,7 +5,7 @@ import { Dictionary } from "farmbot";
/** A function that responds to a particular action from within a
* generated reducer. */
interface ActionHandler<State, Payl = unknown> {
export interface ActionHandler<State, Payl = unknown> {
(state: State, action: ReduxAction<Payl>): State;
}

View File

@ -13,6 +13,7 @@ import { FarmwareState } from "../farmware/interfaces";
import { HelpState } from "../help/reducer";
import { UsageIndex } from "./in_use";
import { SequenceMeta } from "./sequence_meta";
import { AlertReducerState } from "../messages/interfaces";
export type UUID = string;
export type VariableNameSet = Record<string, SequenceMeta | undefined>;
@ -83,6 +84,7 @@ export interface RestResources {
farm_designer: DesignerState;
farmware: FarmwareState;
help: HelpState;
alerts: AlertReducerState;
}
}

View File

@ -20,6 +20,7 @@ import { initialState as designerState } from "../farm_designer/reducer";
import { farmwareState } from "../farmware/reducer";
import { initialState as regimenState } from "../regimens/reducer";
import { initialState as sequenceState } from "../sequences/reducer";
import { initialState as alertState } from "../messages/reducer";
export const emptyState = (): RestResources => {
return {
@ -29,6 +30,7 @@ export const emptyState = (): RestResources => {
farm_designer: designerState,
farmware: farmwareState,
help: helpState,
alerts: alertState
},
loaded: [],
index: {

View File

@ -23,6 +23,7 @@ import {
import { ExecutableType } from "farmbot/dist/resources/api_resources";
import { betterCompact } from "../util";
import { createSequenceMeta } from "./sequence_meta";
import { alertsReducer as alerts } from "../messages/reducer";
export function findByUuid(index: ResourceIndex, uuid: string): TaggedResource {
const x = index.references[uuid];
@ -148,7 +149,8 @@ const consumerReducer = combineReducers<RestResources["consumers"]>({
sequences,
farm_designer,
farmware,
help
help,
alerts
} as any); // tslint:disable-line
/** The resource reducer must have the first say when a resource-related action
@ -162,6 +164,7 @@ export const afterEach = (state: RestResources, a: ReduxAction<unknown>) => {
farm_designer: state.consumers.farm_designer,
farmware: state.consumers.farmware,
help: state.consumers.help,
alerts: state.consumers.alerts
}, a);
return state;
};