Farmbot-Web-App/frontend/redux/subscribers.ts

64 lines
2.4 KiB
TypeScript
Raw Normal View History

2017-06-29 12:54:02 -06:00
import { Everything } from "../interfaces";
import { Store } from "./interfaces";
import { EnvName } from "./interfaces";
2018-03-06 14:18:50 -07:00
import { all } from "../resources/selectors";
import { getWebAppConfig } from "../resources/getters";
import { TaggedResource, TaggedWebAppConfig } from "farmbot";
2017-06-29 12:54:02 -06:00
2018-02-16 15:37:27 -07:00
export function stopThem() { return "You have unsaved work."; }
export function dontStopThem() { }
2017-06-29 12:54:02 -06:00
/** Determine when to notify users about unsaved changes (stop auto-discard). */
const shouldStop =
(allResources: TaggedResource[], config: TaggedWebAppConfig | undefined) => {
const loggedIn = !!localStorage.getItem("session");
2020-01-03 13:04:45 -07:00
const discardUnsaved = config?.body.discard_unsaved;
const sequenceResources = allResources.filter(r => r.kind === "Sequence");
2020-01-03 13:04:45 -07:00
const discardUnsavedSequences = config?.body.discard_unsaved_sequences;
/**
* For the unsaved notification to show, a user must:
* be logged in,
* have at least some unsaved resources,
* not have chosen to discard all unsaved changes,
* and either:
* have an unsaved non-sequence resource,
* or
* not have chosen to discard unsaved sequence changes.
*/
return loggedIn && areSomeDirty(allResources) && !discardUnsaved &&
(!areSomeDirty(sequenceResources) || !discardUnsavedSequences);
};
/** Are any of the provided resources `dirty` (unsaved)? */
const areSomeDirty = (resources: TaggedResource[]) => {
const dirty = resources.filter(r => !!r.specialStatus);
const total = dirty.length;
return total !== 0;
};
2017-06-29 12:54:02 -06:00
/** Subscribe to the store. Stop the user from exiting if any part of the
* state tree contains `dirty` resources that can't be discarded. */
2018-03-06 13:39:41 -07:00
export function unsavedCheck(state: Everything) {
const { index } = state.resources;
const resources = all(index);
2018-03-06 13:39:41 -07:00
const conf = getWebAppConfig(index);
2018-03-06 15:35:35 -07:00
window.onbeforeunload = shouldStop(resources, conf) ? stopThem : dontStopThem;
2017-06-29 12:54:02 -06:00
}
2018-01-04 11:23:06 -07:00
export interface Subscription { fn: (state: Everything) => void; env: EnvName; }
2017-06-29 12:54:02 -06:00
/** To make it easier to manage all things watching the state tree,
* we keep subscriber functions in this array. */
export const subscriptions: Subscription[] = [{ env: "*", fn: unsavedCheck }];
2017-06-29 12:54:02 -06:00
export function registerSubscribers(store: Store) {
2017-08-28 05:49:13 -06:00
const ENV_LIST = [process.env.NODE_ENV, "*"];
2017-06-29 12:54:02 -06:00
subscriptions.forEach(function (s) {
ENV_LIST.includes &&
ENV_LIST.includes(s.env) &&
2020-01-03 13:04:45 -07:00
store.subscribe(() => s.fn?.(store.getState()));
2017-06-29 12:54:02 -06:00
});
2017-08-15 14:21:41 -06:00
}