-
Notifications
You must be signed in to change notification settings - Fork 4
/
ContextProvider.tsx
127 lines (116 loc) · 3.89 KB
/
ContextProvider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import * as React from "react";
import { Store } from "@reduxjs/toolkit";
import * as PropTypes from "prop-types";
import buildStore, { RootState } from "../store";
import {
DashboardCollectionsBarChart,
FeatureFlags,
PathFor,
} from "../interfaces";
import Admin from "../models/Admin";
import PathForProvider from "@thepalaceproject/web-opds-client/lib/components/context/PathForContext";
import ActionCreator from "../actions";
import AppContextProvider, { AppContextType } from "../context/appContext";
// Note: Not all elements of these props make it into the `ContextProvider`.
// Some are exposed only through the `AppContextProvider` component (which
// this component wraps).
// TODO: We should get this interface to the point where we can just extend
// the `ConfigurationSettings` interface.
export interface ContextProviderProps extends React.Props<ContextProvider> {
store?: Store<RootState>;
csrfToken: string;
showCircEventsDownload?: boolean;
settingUp?: boolean;
email?: string;
roles?: {
role: string;
library?: string;
}[];
featureFlags: FeatureFlags;
quicksightPagePath?: string;
dashboardCollectionsBarChart?: DashboardCollectionsBarChart;
}
/** Provides a redux store, configuration options, and a function to create URLs
as context to admin interface pages. */
export default class ContextProvider extends React.Component<
ContextProviderProps
> {
store: Store<RootState>;
admin: Admin;
pathFor: PathFor;
constructor(props) {
super(props);
this.store = props.store ?? buildStore();
this.admin = new Admin(props.roles || [], props.email || null);
this.pathFor = (collectionUrl: string, bookUrl: string, tab?: string) => {
let path = "/admin/web";
path += collectionUrl
? `/collection/${this.prepareCollectionUrl(collectionUrl)}`
: "";
path += bookUrl ? `/book/${this.prepareBookUrl(bookUrl)}` : "";
path += tab ? `/tab/${tab}` : "";
return path;
};
}
componentDidMount() {
this.storeConfiguration();
}
storeConfiguration() {
const actions = new ActionCreator();
this.store.dispatch(actions.setFeatureFlags(this.props.featureFlags));
}
prepareCollectionUrl(url: string): string {
return encodeURIComponent(
url
.replace(document.location.origin + "/", "")
.replace(/\/$/, "")
.replace(/^\//, "")
);
}
prepareBookUrl(url: string): string {
const regexp = new RegExp(document.location.origin + "/(.*)/works/(.*)");
const match = regexp.exec(url);
if (match) {
const library = match[1];
const work = match[2];
return encodeURIComponent(library + "/" + work);
} else {
return url;
}
}
static childContextTypes: React.ValidationMap<object> = {
editorStore: PropTypes.object.isRequired,
csrfToken: PropTypes.string.isRequired,
showCircEventsDownload: PropTypes.bool.isRequired,
settingUp: PropTypes.bool.isRequired,
admin: PropTypes.object.isRequired,
featureFlags: PropTypes.object.isRequired,
};
getChildContext() {
return {
editorStore: this.store,
csrfToken: this.props.csrfToken,
showCircEventsDownload: this.props.showCircEventsDownload || false,
settingUp: this.props.settingUp || false,
admin: this.admin,
featureFlags: this.props.featureFlags,
};
}
render() {
const appContextValue: AppContextType = {
csrfToken: this.props.csrfToken,
settingUp: this.props.settingUp,
admin: this.admin,
featureFlags: this.props.featureFlags,
quicksightPagePath: this.props.quicksightPagePath,
dashboardCollectionsBarChart: this.props.dashboardCollectionsBarChart,
};
return (
<PathForProvider pathFor={this.pathFor}>
<AppContextProvider value={appContextValue}>
{React.Children.only(this.props.children) as JSX.Element}
</AppContextProvider>
</PathForProvider>
);
}
}