Merge branch '20219-log-api' into main. Closes #20219
[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 & WithStyles<CssRules> & {
35     openBanner: Function,
36     closeBanner: Function,
37 };
38
39 const mapStateToProps = (state: RootState): BannerProps => ({
40     isOpen: state.banner.isOpen,
41     bannerUUID: state.auth.config.clusterConfig.Workbench.BannerUUID,
42     keepWebInlineServiceUrl: state.auth.config.keepWebInlineServiceUrl,
43 });
44
45 const mapDispatchToProps = (dispatch: Dispatch) => ({
46     openBanner: () => dispatch<any>(bannerActions.openBanner()),
47     closeBanner: () => dispatch<any>(bannerActions.closeBanner()),
48 });
49
50 export const BANNER_LOCAL_STORAGE_KEY = 'bannerFileData';
51
52 export const BannerComponent = (props: BannerComponentProps) => {
53     const { 
54         isOpen,
55         openBanner,
56         closeBanner,
57         bannerUUID,
58         keepWebInlineServiceUrl
59     } = props;
60     const [bannerContents, setBannerContents] = useState(`<h1>Loading ...</h1>`)
61
62     const onConfirm = useCallback(() => {
63         closeBanner();
64     }, [closeBanner])
65
66     useEffect(() => {
67         if (!!bannerUUID && bannerUUID !== "") {
68             servicesProvider.getServices().collectionService.files(bannerUUID)
69                 .then(results => {
70                     const bannerFileData = results.find(({name}) => name === 'banner.html');
71                     const result = localStorage.getItem(BANNER_LOCAL_STORAGE_KEY);
72
73                     if (result && result === JSON.stringify(bannerFileData) && !isOpen) {
74                         return;
75                     }
76
77                     if (bannerFileData) {
78                         servicesProvider.getServices()
79                             .collectionService.getFileContents(bannerFileData)
80                             .then(data => {
81                                 setBannerContents(data);
82                                 openBanner();
83                                 localStorage.setItem(BANNER_LOCAL_STORAGE_KEY, JSON.stringify(bannerFileData));
84                             });
85                     }
86                 });
87         }
88     }, [bannerUUID, keepWebInlineServiceUrl, openBanner, isOpen]);
89
90     return (
91         <Dialog open={isOpen}>
92             <div data-cy='confirmation-dialog'>
93                 <DialogContent className={props.classes.dialogContent}>
94                     <div dangerouslySetInnerHTML={{ __html: bannerContents }}></div>
95                 </DialogContent>
96                 <DialogActions style={{ margin: '0px 24px 24px' }}>
97                     <Button
98                         data-cy='confirmation-dialog-ok-btn'
99                         variant='contained'
100                         color='primary'
101                         type='submit'
102                         onClick={onConfirm}>
103                         Close
104                     </Button>
105                 </DialogActions>
106             </div>
107         </Dialog>
108     );
109 }
110
111 export const Banner = withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(BannerComponent));