7e39186c09f8d852f7868ed26579dd0a4e619eba
[arvados.git] / src / views-components / baner / banner.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React, { useState, useCallback, useEffect } from "react";
6 import { Dialog, DialogContent, DialogActions, Button, StyleRulesCallback, withStyles, WithStyles } from "@material-ui/core";
7 import { connect } from "react-redux";
8 import { RootState } from "store/store";
9 import bannerActions from "store/banner/banner-action";
10 import { ArvadosTheme } from "common/custom-theme";
11 import servicesProvider from "common/service-provider";
12 import { Dispatch } from "redux";
13
14 type CssRules = "dialogContent" | "dialogContentIframe";
15
16 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
17     dialogContent: {
18         minWidth: "550px",
19         minHeight: "500px",
20         display: "block",
21     },
22     dialogContentIframe: {
23         minWidth: "550px",
24         minHeight: "500px",
25     },
26 });
27
28 interface BannerProps {
29     isOpen: boolean;
30     bannerUUID?: string;
31     keepWebInlineServiceUrl: string;
32 }
33
34 type BannerComponentProps = BannerProps &
35     WithStyles<CssRules> & {
36         openBanner: Function;
37         closeBanner: Function;
38     };
39
40 const mapStateToProps = (state: RootState): BannerProps => ({
41     isOpen: state.banner.isOpen,
42     bannerUUID: state.auth.config.clusterConfig.Workbench.BannerUUID,
43     keepWebInlineServiceUrl: state.auth.config.keepWebInlineServiceUrl,
44 });
45
46 const mapDispatchToProps = (dispatch: Dispatch) => ({
47     openBanner: () => dispatch<any>(bannerActions.openBanner()),
48     closeBanner: () => dispatch<any>(bannerActions.closeBanner()),
49 });
50
51 export const BANNER_LOCAL_STORAGE_KEY = "bannerFileData";
52
53 export const BannerComponent = (props: BannerComponentProps) => {
54     const { isOpen, openBanner, closeBanner, bannerUUID, keepWebInlineServiceUrl } = props;
55     const [bannerContents, setBannerContents] = useState(`<h1>Loading ...</h1>`);
56
57     const onConfirm = useCallback(() => {
58         closeBanner();
59     }, [closeBanner]);
60
61     useEffect(() => {
62         if (!!bannerUUID && bannerUUID !== "") {
63             servicesProvider
64                 .getServices()
65                 .collectionService.files(bannerUUID)
66                 .then(results => {
67                     const bannerFileData = results.find(({ name }) => name === "banner.html");
68                     const result = localStorage.getItem(BANNER_LOCAL_STORAGE_KEY);
69
70                     if (result && result === JSON.stringify(bannerFileData) && !isOpen) {
71                         return;
72                     }
73
74                     if (bannerFileData) {
75                         servicesProvider
76                             .getServices()
77                             .collectionService.getFileContents(bannerFileData)
78                             .then(data => {
79                                 setBannerContents(data);
80                                 openBanner();
81                                 localStorage.setItem(BANNER_LOCAL_STORAGE_KEY, JSON.stringify(bannerFileData));
82                             });
83                     }
84                 });
85         }
86     }, [bannerUUID, keepWebInlineServiceUrl, openBanner, isOpen]);
87
88     return (
89         <Dialog
90             open={isOpen}
91             maxWidth="md"
92         >
93             <div data-cy="confirmation-dialog">
94                 <DialogContent className={props.classes.dialogContent}>
95                     <div dangerouslySetInnerHTML={{ __html: bannerContents }}></div>
96                 </DialogContent>
97                 <DialogActions style={{ margin: "0px 24px 24px" }}>
98                     <Button
99                         data-cy="confirmation-dialog-ok-btn"
100                         variant="contained"
101                         color="primary"
102                         type="submit"
103                         onClick={onConfirm}
104                     >
105                         Close
106                     </Button>
107                 </DialogActions>
108             </div>
109         </Dialog>
110     );
111 };
112
113 export const Banner = withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(BannerComponent));