diff --git a/db/migrate/20190729134954_add_user_interface_read_only_mode_to_web_app_config.rb b/db/migrate/20190729134954_add_user_interface_read_only_mode_to_web_app_config.rb new file mode 100644 index 000000000..8ccfb7167 --- /dev/null +++ b/db/migrate/20190729134954_add_user_interface_read_only_mode_to_web_app_config.rb @@ -0,0 +1,10 @@ +class AddUserInterfaceReadOnlyModeToWebAppConfig < ActiveRecord::Migration[5.2] + def change + safety_assured do + add_column :web_app_configs, + :user_interface_read_only_mode, + :boolean, + default: false + end + end +end diff --git a/db/structure.sql b/db/structure.sql index ce6ec755d..7882b116f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1663,7 +1663,8 @@ CREATE TABLE public.web_app_configs ( hide_sensors boolean DEFAULT false, confirm_plant_deletion boolean DEFAULT true, discard_unsaved_sequences boolean DEFAULT false, - confirm_sequence_deletion boolean DEFAULT true + confirm_sequence_deletion boolean DEFAULT true, + user_interface_read_only_mode boolean DEFAULT false ); @@ -3149,6 +3150,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20190701155706'), ('20190709194037'), ('20190715214412'), -('20190722160305'); +('20190722160305'), +('20190729134954'); diff --git a/frontend/__test_support__/fake_state/resources.ts b/frontend/__test_support__/fake_state/resources.ts index 0c67da0b7..90948d740 100644 --- a/frontend/__test_support__/fake_state/resources.ts +++ b/frontend/__test_support__/fake_state/resources.ts @@ -318,6 +318,7 @@ export function fakeWebAppConfig(): TaggedWebAppConfig { disable_emergency_unlock_confirmation: false, map_size_x: 2900, map_size_y: 1400, + user_interface_read_only_mode: false }); } diff --git a/frontend/account/labs/labs_features_list_data.ts b/frontend/account/labs/labs_features_list_data.ts index 596f6935c..2e1b58207 100644 --- a/frontend/account/labs/labs_features_list_data.ts +++ b/frontend/account/labs/labs_features_list_data.ts @@ -72,6 +72,13 @@ export const fetchLabFeatures = value: false, displayInvert: true, }, + { + name: t("User Interface Read Only Mode"), + description: t(Content.USER_INTERFACE_READ_ONLY_MODE), + storageKey: BooleanSetting.user_interface_read_only_mode, + value: false, + displayInvert: false, + } ].map(fetchSettingValue(getConfigValue))); /** Always allow toggling from true => false (deactivate). diff --git a/frontend/constants.ts b/frontend/constants.ts index c35bd7e15..ff6496083 100644 --- a/frontend/constants.ts +++ b/frontend/constants.ts @@ -538,6 +538,10 @@ export namespace Content { export const EMERGENCY_UNLOCK_CONFIRM_CONFIG = trim(`Confirm when unlocking FarmBot after an emergency stop.`); + export const USER_INTERFACE_READ_ONLY_MODE = + trim(`Disallow account data changes. This does + not prevent Farmwares or FarmBot OS from changing settings.`); + export const CONFIRM_EMERGENCY_UNLOCK_CONFIRM_DISABLE = trim(`Warning! When disabled, clicking the UNLOCK button will immediately unlock FarmBot instead of confirming that it is safe to do so. diff --git a/frontend/resources/getters.ts b/frontend/resources/getters.ts index 01616b3f0..f5a7ad2d0 100644 --- a/frontend/resources/getters.ts +++ b/frontend/resources/getters.ts @@ -8,7 +8,6 @@ import { /** @fileoverview Resource selectors for SINGULAR resources. */ -/** Wow! */ export const getFbosConfig = (i: ResourceIndex): TaggedFbosConfig | undefined => findAll(i, "FbosConfig")[0]; diff --git a/frontend/resources/selectors.ts b/frontend/resources/selectors.ts index e6bc8e688..298fee47e 100644 --- a/frontend/resources/selectors.ts +++ b/frontend/resources/selectors.ts @@ -249,3 +249,14 @@ export function getUserAccountSettings(index: ResourceIndex): TaggedUser { export function all(index: ResourceIndex) { return betterCompact(Object.keys(index.all).map(uuid => index.references[uuid])); } + +/** Returns `true` if the user is allowed to modify account data. + * This is a helper function of the "readonly" account lock. */ +export function appIsReadonly(index: ResourceIndex) { + const conf = getWebAppConfig(index); + if (conf) { + return conf.body.user_interface_read_only_mode; + } else { + return true; // Don't allow data updates until config is found + } +} diff --git a/frontend/session_keys.ts b/frontend/session_keys.ts index 4403b2c6d..ac73dcf5b 100644 --- a/frontend/session_keys.ts +++ b/frontend/session_keys.ts @@ -44,6 +44,7 @@ export const BooleanSetting: Record = { discard_unsaved: "discard_unsaved", time_format_24_hour: "time_format_24_hour", disable_emergency_unlock_confirmation: "disable_emergency_unlock_confirmation", + user_interface_read_only_mode: "user_interface_read_only_mode", /** Farmware settings */ show_first_party_farmware: "show_first_party_farmware", diff --git a/package.json b/package.json index 8306c2621..485f79fdd 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "coveralls": "3.0.5", "enzyme": "3.10.0", "enzyme-adapter-react-16": "1.14.0", - "farmbot": "8.0.3-rc1", + "farmbot": "8.0.3", "i18next": "17.0.6", "lodash": "4.17.15", "markdown-it": "9.0.1",