Skip to content

Commit

Permalink
Merge branch 'staging' into time_format_24_hour
Browse files Browse the repository at this point in the history
  • Loading branch information
RickCarlino committed Apr 15, 2019
2 parents 8574ae3 + 8faf016 commit 76d3938
Show file tree
Hide file tree
Showing 24 changed files with 163 additions and 61 deletions.
13 changes: 12 additions & 1 deletion frontend/__test_support__/fake_state/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
TaggedToolSlotPointer,
TaggedFarmwareEnv,
TaggedFarmwareInstallation,
TaggedEnigma,
} from "farmbot";
import { fakeResource } from "../fake_resource";
import { ExecutableType, PinBindingType } from "farmbot/dist/resources/api_resources";
Expand Down Expand Up @@ -307,7 +308,8 @@ export function fakeWebAppConfig(): TaggedWebAppConfig {
home_button_homing: false,
show_motor_plot: false,
show_historic_points: false,
time_format_24_hour: false
time_format_24_hour: false,
show_pins: false,
});
}

Expand Down Expand Up @@ -423,3 +425,12 @@ export function fakeFarmwareInstallation(): TaggedFarmwareInstallation {
package_error: undefined,
});
}

export function fakeEnigma(): TaggedEnigma {
return fakeResource("Enigma", {
uuid: "uuid",
created_at: 123,
problem_tag: "api.noun.verb",
priority: 100,
});
}
1 change: 1 addition & 0 deletions frontend/__test_support__/resource_index_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ const KIND_PRIORITY: ResourceLookupTable = {
Point: 1,
Sensor: 1,
Tool: 1,
Enigma: 1,
SensorReading: 2,
Sequence: 2,
Regimen: 3,
Expand Down
2 changes: 2 additions & 0 deletions frontend/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,7 @@ export class API {
get farmwareInstallationPath() {
return `${this.baseUrl}/api/farmware_installations/`;
}
/** /api/enigmas/:id */
get enigmaPath() { return `${this.baseUrl}/api/enigmas/`; }
get syncPatch() { return `${this.baseUrl}/api/device/sync/`; }
}
1 change: 1 addition & 0 deletions frontend/api/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export function urlFor(tag: ResourceName) {
PlantTemplate: API.current.plantTemplatePath,
FarmwareEnv: API.current.farmwareEnvPath,
FarmwareInstallation: API.current.farmwareInstallationPath,
Enigma: API.current.enigmaPath,
};
const url = OPTIONS[tag];
if (url) {
Expand Down
7 changes: 7 additions & 0 deletions frontend/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,13 @@ export namespace Content {
trim(`Export request received. Please allow up to 10 minutes for
delivery.`);

export const SEED_DATA_SELECTION =
trim(`To finish setting up your account and FarmBot, please select which
FarmBot you have. Once you make a selection, we'll automatically add some
tools, sensors, peripherals, sequences, and more to get you up and running
faster. If you want to start completely from scratch, feel free to select
"Custom bot" and we won't change a thing.`);

// App Settings
export const CONFIRM_STEP_DELETION =
trim(`Show a confirmation dialog when the sequence delete step
Expand Down
8 changes: 8 additions & 0 deletions frontend/css/_mobile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@
transform: translateX(0)
}
}

.controls-page {
@media (min-width:992px) {
.col-md-offset-1 {
margin-left: 5%;
}
}
}
6 changes: 6 additions & 0 deletions frontend/css/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,12 @@ ul {
.bp3-popover-target {
float: right;
}
@media screen and (max-width: 1075px) {
padding-left: 15px !important;
}
@media screen and (max-width: 974px) {
padding-left: 0 !important;
}
}

.logs-settings-menu {
Expand Down
12 changes: 10 additions & 2 deletions frontend/logs/__tests__/alerts_test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ const FIRMWARE_MISSING_ALERT: Alert = {
uuid: "uuid",
};

const SEED_DATA_MISSING_ALERT: Alert = {
created_at: 123,
problem_tag: "api.seed_data.missing",
priority: 300,
uuid: "uuid",
};

const UNKNOWN_ALERT: Alert = {
created_at: 123,
problem_tag: "farmbot_os.firmware.alert",
Expand Down Expand Up @@ -41,10 +48,11 @@ describe("<Alerts />", () => {

it("renders alerts", () => {
const p = fakeProps();
p.alerts = [FIRMWARE_MISSING_ALERT];
p.alerts = [FIRMWARE_MISSING_ALERT, SEED_DATA_MISSING_ALERT];
const wrapper = mount(<Alerts {...p} />);
expect(wrapper.text()).toContain("1");
expect(wrapper.text()).toContain("2");
expect(wrapper.text()).toContain("Your device has no firmware installed");
expect(wrapper.text()).toContain("Choose your FarmBot");
});

it("renders unknown alert", () => {
Expand Down
31 changes: 28 additions & 3 deletions frontend/logs/__tests__/state_to_props_test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
let mockDev = false;
jest.mock("../../account/dev/dev_support", () => ({
DevSettings: {
futureFeaturesEnabled: () => mockDev,
}
}));

import { mapStateToProps } from "../state_to_props";
import { fakeState } from "../../__test_support__/fake_state";
import { buildResourceIndex } from "../../__test_support__/resource_index_builder";
import { TaggedLog } from "farmbot";
import { times } from "lodash";
import { fakeFbosConfig, fakeLog } from "../../__test_support__/fake_state/resources";
import {
fakeFbosConfig, fakeLog, fakeEnigma
} from "../../__test_support__/fake_state/resources";

describe("mapStateToProps()", () => {
function fakeLogs(count: number): TaggedLog[] {
Expand Down Expand Up @@ -45,9 +54,25 @@ describe("mapStateToProps()", () => {

it("handles undefined", () => {
const state = fakeState();
// tslint:disable-next-line:no-any
state.bot.hardware.enigmas = undefined as any;
state.bot.hardware.enigmas = undefined;
const props = mapStateToProps(state);
expect(props.alerts).toEqual([]);
});

it("doesn't show API alerts", () => {
const state = fakeState();
state.resources = buildResourceIndex([fakeEnigma()]);
mockDev = false;
const props = mapStateToProps(state);
expect(props.alerts).toEqual([]);
});

it("shows API alerts", () => {
const state = fakeState();
const enigma = fakeEnigma();
state.resources = buildResourceIndex([enigma]);
mockDev = true;
const props = mapStateToProps(state);
expect(props.alerts).toEqual([enigma.body]);
});
});
35 changes: 28 additions & 7 deletions frontend/logs/alerts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { formatLogTime } from "./index";
import { TimeSettings } from "../interfaces";
import { Enigma } from "farmbot";
import { sortBy } from "lodash";
import { Content } from "../constants";

export interface AlertsProps {
alerts: Alert[];
Expand Down Expand Up @@ -71,11 +72,12 @@ export const FirmwareAlerts = (props: FirmwareAlertsProps) => {
const firmwareAlerts = sortAlerts(alerts)
.filter(x => splitTag(x.problem_tag).noun === "firmware");
return <div className="firmware-alerts">
{firmwareAlerts.map((x, i) =>
<AlertCard key={i}
alert={x}
apiFirmwareValue={props.apiFirmwareValue}
timeSettings={props.timeSettings} />)}
{firmwareAlerts.filter(x => x.problem_tag && x.priority && x.created_at)
.map((x, i) =>
<AlertCard key={i}
alert={x}
apiFirmwareValue={props.apiFirmwareValue}
timeSettings={props.timeSettings} />)}
</div>;
};

Expand All @@ -94,6 +96,10 @@ const AlertCard = (props: AlertCardProps) => {
createdAt={props.alert.created_at}
apiFirmwareValue={props.apiFirmwareValue}
timeSettings={props.timeSettings} />;
case "api.seed_data.missing":
return <SeedDataMissing
createdAt={props.alert.created_at}
timeSettings={props.timeSettings} />;
default:
return UnknownAlert(props.alert, props.timeSettings);
}
Expand All @@ -118,12 +124,15 @@ const UnknownAlert = (alert: Alert, timeSettings: TimeSettings) => {
</div>;
};

interface FirmwareMissingProps {
interface CommonAlertCardProps {
createdAt: number;
apiFirmwareValue: string | undefined;
timeSettings: TimeSettings;
}

interface FirmwareMissingProps extends CommonAlertCardProps {
apiFirmwareValue: string | undefined;
}

const FirmwareMissing = (props: FirmwareMissingProps) =>
<div className="problem-alert firmware-missing-alert">
<div className="problem-alert-title">
Expand All @@ -138,3 +147,15 @@ const FirmwareMissing = (props: FirmwareMissingProps) =>
botOnline={true} />
</div>
</div>;

const SeedDataMissing = (props: CommonAlertCardProps) =>
<div className="problem-alert seed-data-missing-alert">
<div className="problem-alert-title">
<i className="fa fa-exclamation-triangle" />
<h3>{t("Choose your FarmBot")}</h3>
<p>{formatLogTime(props.createdAt, props.timeSettings)}</p>
</div>
<div className="problem-alert-content">
<p>{Content.SEED_DATA_SELECTION}</p>
</div>
</div>;
11 changes: 9 additions & 2 deletions frontend/logs/state_to_props.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Everything } from "../interfaces";
import { selectAllLogs, maybeGetTimeSettings } from "../resources/selectors";
import {
selectAllLogs, maybeGetTimeSettings, selectAllEnigmas
} from "../resources/selectors";
import { LogsProps } from "./interfaces";
import {
sourceFbosConfigValue
Expand All @@ -11,6 +13,7 @@ import { getWebAppConfigValue } from "../config_storage/actions";
import { getFbosConfig } from "../resources/getters";
import { chain } from "lodash";
import { isFwHardwareValue } from "../devices/components/fbos_settings/board_type";
import { DevSettings } from "../account/dev/dev_support";

/** Take the specified number of logs after sorting by time created. */
export function takeSortedLogs(
Expand All @@ -28,13 +31,17 @@ export function mapStateToProps(props: Everything): LogsProps {
const sourceFbosConfig =
sourceFbosConfigValue(fbosConfig, hardware.configuration);
const apiFirmwareValue = sourceFbosConfig("firmware_hardware").value;
const botAlerts = betterCompact(Object.values(props.bot.hardware.enigmas || {}));
const apiAlerts = selectAllEnigmas(props.resources.index).map(x => x.body);
const alerts =
botAlerts.concat(DevSettings.futureFeaturesEnabled() ? apiAlerts : []);
return {
dispatch: props.dispatch,
sourceFbosConfig,
logs: takeSortedLogs(250, props.resources.index),
timeSettings: maybeGetTimeSettings(props.resources.index),
getConfigValue: getWebAppConfigValue(() => props),
alerts: betterCompact(Object.values(props.bot.hardware.enigmas || {})),
alerts,
apiFirmwareValue: isFwHardwareValue(apiFirmwareValue)
? apiFirmwareValue : undefined,
};
Expand Down
3 changes: 2 additions & 1 deletion frontend/resources/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export const emptyState = (): RestResources => {
PinBinding: {},
PlantTemplate: {},
SavedGarden: {},
DiagnosticDump: {}
DiagnosticDump: {},
Enigma: {},
},
byKindAndId: {},
references: {},
Expand Down
3 changes: 3 additions & 0 deletions frontend/resources/selectors_by_kind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
TaggedPlantTemplate,
TaggedFarmwareEnv,
TaggedFarmwareInstallation,
TaggedEnigma,
} from "farmbot";
import {
isTaggedResource,
Expand Down Expand Up @@ -99,6 +100,8 @@ export const selectAllWebcamFeeds =
(i: ResourceIndex) => findAll<TaggedWebcamFeed>(i, "WebcamFeed");
export const selectAllSavedPeripherals =
(input: ResourceIndex) => selectAllPeripherals(input).filter(isSaved);
export const selectAllEnigmas =
(i: ResourceIndex) => findAll<TaggedEnigma>(i, "Enigma");

export const findByKindAndId = <T extends TaggedResource>(
i: ResourceIndex, kind: T["kind"], id: number | undefined): T => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,8 @@ describe("<SequenceEditorMiddleActive/>", () => {
farmwareConfigs: {},
},
shouldDisplay: jest.fn(),
confirmStepDeletion: false,
getWebAppConfigValue: jest.fn(),
menuOpen: false,
showPins: true,
};
};

Expand Down Expand Up @@ -254,13 +253,12 @@ describe("<SequenceSettingsMenu />", () => {
it("renders settings", () => {
const wrapper = mount(<SequenceSettingsMenu
dispatch={jest.fn()}
confirmStepDeletion={false}
showPins={false} />);
getWebAppConfigValue={jest.fn()} />);
wrapper.find("button").first().simulate("click");
expect(setWebAppConfigValue).toHaveBeenCalledWith(
BooleanSetting.confirm_step_deletion, true);
wrapper.find("button").last().simulate("click");
expect(setWebAppConfigValue).toHaveBeenCalledWith(
"show_pins", true);
BooleanSetting.show_pins, true);
});
});
3 changes: 1 addition & 2 deletions frontend/sequences/__tests__/sequence_editor_middle_test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ describe("<SequenceEditorMiddle/>", () => {
farmwareConfigs: {},
},
shouldDisplay: jest.fn(),
confirmStepDeletion: false,
getWebAppConfigValue: jest.fn(),
menuOpen: false,
showPins: true,
};
}

Expand Down
3 changes: 1 addition & 2 deletions frontend/sequences/__tests__/sequences_test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ describe("<Sequences/>", () => {
farmwareConfigs: {},
},
shouldDisplay: jest.fn(),
confirmStepDeletion: false,
getWebAppConfigValue: jest.fn(),
menuOpen: false,
stepIndex: undefined,
showPins: true,
});

it("renders", () => {
Expand Down
10 changes: 4 additions & 6 deletions frontend/sequences/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { StepMoveDataXfer, StepSpliceDataXfer } from "../draggable/interfaces";
import { TaggedSequence } from "farmbot";
import { ResourceIndex, VariableNameSet, UUID } from "../resources/interfaces";
import { ShouldDisplay } from "../devices/interfaces";
import { GetWebAppConfigValue } from "../config_storage/actions";

export interface HardwareFlags {
findHomeEnabled: Record<Xyz, boolean>;
Expand Down Expand Up @@ -44,10 +45,9 @@ export interface Props {
hardwareFlags: HardwareFlags;
farmwareInfo: FarmwareInfo;
shouldDisplay: ShouldDisplay;
confirmStepDeletion: boolean;
getWebAppConfigValue: GetWebAppConfigValue;
menuOpen: boolean;
stepIndex: number | undefined;
showPins: boolean;
}

export interface SequenceEditorMiddleProps {
Expand All @@ -58,9 +58,8 @@ export interface SequenceEditorMiddleProps {
hardwareFlags: HardwareFlags;
farmwareInfo: FarmwareInfo;
shouldDisplay: ShouldDisplay;
confirmStepDeletion: boolean;
getWebAppConfigValue: GetWebAppConfigValue;
menuOpen: boolean;
showPins: boolean;
}

export interface ActiveMiddleProps extends SequenceEditorMiddleProps {
Expand All @@ -76,8 +75,7 @@ export interface SequenceHeaderProps {
menuOpen: boolean;
variablesCollapsed: boolean;
toggleVarShow: () => void;
confirmStepDeletion: boolean;
showPins: boolean;
getWebAppConfigValue: GetWebAppConfigValue;
}

export type ChannelName = ALLOWED_CHANNEL_NAMES;
Expand Down
Loading

0 comments on commit 76d3938

Please sign in to comment.