|
| 1 | +import{loadComps}from"bootstrap/view"; |
| 2 | +import{initApp}from"util/commonUtils"; |
| 3 | +import{connect,Provider}from"react-redux"; |
| 4 | +import{createRoot}from"react-dom/client"; |
| 5 | +importtype{AppState}from"@lowcoder-ee/redux/reducers"; |
| 6 | +import{isFetchUserFinished}from"@lowcoder-ee/redux/selectors/usersSelectors"; |
| 7 | +import{getIsCommonSettingFetched}from"@lowcoder-ee/redux/selectors/commonSettingSelectors"; |
| 8 | +import{getBrandingConfig}from"@lowcoder-ee/redux/selectors/configSelectors"; |
| 9 | +import{buildMaterialPreviewURL}from"@lowcoder-ee/util/materialUtils"; |
| 10 | +import{favicon}from"@lowcoder-ee/assets/images"; |
| 11 | +import{trans}from"@lowcoder-ee/i18n"; |
| 12 | +import{fetchUserAction}from"@lowcoder-ee/redux/reduxActions/userActions"; |
| 13 | +import{fetchConfigAction}from"@lowcoder-ee/redux/reduxActions/configActions"; |
| 14 | +import{fetchHomeData}from"@lowcoder-ee/redux/reduxActions/applicationActions"; |
| 15 | +import{packageMetaReadyAction,setLowcoderCompsLoading}from"@lowcoder-ee/redux/reduxActions/npmPluginActions"; |
| 16 | +import{getNpmPackageMeta}from"@lowcoder-ee/comps/utils/remote"; |
| 17 | +import{reduxStore}from"redux/store/store"; |
| 18 | +importReactfrom"react"; |
| 19 | +import{hasQueryParam}from"@lowcoder-ee/util/urlUtils"; |
| 20 | +importhistoryfrom"@lowcoder-ee/util/history"; |
| 21 | +import{ |
| 22 | +APP_EDITOR_URL, |
| 23 | +isAuthUnRequired, |
| 24 | +}from"@lowcoder-ee/constants/routesURL"; |
| 25 | +import{ProductLoading}from"@lowcoder-ee/components/ProductLoading"; |
| 26 | +import{Helmet}from"react-helmet"; |
| 27 | +import{SystemWarning}from"@lowcoder-ee/components/SystemWarning"; |
| 28 | +import{Router,Switch}from"react-router-dom"; |
| 29 | +importLazyRoutefrom"@lowcoder-ee/components/LazyRoute"; |
| 30 | +import{defaultasConfigProvider}from"antd/es/config-provider"; |
| 31 | +import{getAntdLocale}from"@lowcoder-ee/i18n/antdLocale"; |
| 32 | +import{defaultasApp}from"antd/es/app"; |
| 33 | +importGlobalInstancesfrom"components/GlobalInstances"; |
| 34 | +constLazyAppEditor=React.lazy(()=>import("pages/editor/AppEditor")); |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | +constmapStateToProps=(state:AppState)=>({ |
| 39 | +isFetchUserFinished:isFetchUserFinished(state), |
| 40 | +getIsCommonSettingFetched:getIsCommonSettingFetched(state), |
| 41 | +orgDev:state.ui.users.user.orgDev, |
| 42 | +currentUserId:state.ui.users.currentUser.id, |
| 43 | +currentUserAnonymous:state.ui.users.user.isAnonymous, |
| 44 | +currentOrgId:state.ui.users.user.currentOrgId, |
| 45 | +defaultHomePage:state.ui.application.homeOrg?.commonSettings.defaultHomePage, |
| 46 | +fetchHomeDataFinished:Boolean(state.ui.application.homeOrg?.commonSettings), |
| 47 | +favicon:getBrandingConfig(state)?.favicon |
| 48 | + ?buildMaterialPreviewURL(getBrandingConfig(state)?.favicon!) |
| 49 | + :favicon, |
| 50 | +brandName:getBrandingConfig(state)?.brandName??trans("productName"), |
| 51 | +uiLanguage:state.ui.users.user.uiLanguage, |
| 52 | +}); |
| 53 | + |
| 54 | + |
| 55 | +constmapDispatchToProps=(dispatch:any)=>({ |
| 56 | +getCurrentUser:()=>{ |
| 57 | +dispatch(fetchUserAction()); |
| 58 | +}, |
| 59 | +fetchConfig:(orgId?:string)=>dispatch(fetchConfigAction(orgId)), |
| 60 | +fetchHomeData:(currentUserAnonymous:boolean|undefined)=>{ |
| 61 | +dispatch(fetchHomeData({})); |
| 62 | +}, |
| 63 | +fetchLowcoderCompVersions:async()=>{ |
| 64 | +try{ |
| 65 | +dispatch(setLowcoderCompsLoading(true)); |
| 66 | +constpackageMeta=awaitgetNpmPackageMeta('lowcoder-comps'); |
| 67 | +if(packageMeta?.versions){ |
| 68 | +dispatch(packageMetaReadyAction('lowcoder-comps',packageMeta)); |
| 69 | +} |
| 70 | +dispatch(setLowcoderCompsLoading(false)); |
| 71 | +}catch(_){ |
| 72 | +dispatch(setLowcoderCompsLoading(false)); |
| 73 | +} |
| 74 | +}, |
| 75 | +}); |
| 76 | + |
| 77 | +constWrapper=(props:{children:React.ReactNode,language:string})=>( |
| 78 | +<ConfigProvider |
| 79 | +theme={{hashed:false}} |
| 80 | +locale={getAntdLocale(props.language)} |
| 81 | +> |
| 82 | +<App> |
| 83 | +<GlobalInstances/> |
| 84 | +{props.children} |
| 85 | +</App> |
| 86 | +</ConfigProvider> |
| 87 | +); |
| 88 | + |
| 89 | +typeAppIndexProps={ |
| 90 | +isFetchUserFinished:boolean; |
| 91 | +getIsCommonSettingFetched:boolean; |
| 92 | +currentOrgId?:string; |
| 93 | +currentUserId:string; |
| 94 | +currentUserAnonymous:boolean; |
| 95 | +orgDev:boolean; |
| 96 | +defaultHomePage:string|null|undefined; |
| 97 | +fetchHomeDataFinished:boolean; |
| 98 | +fetchConfig:(orgId?:string)=>void; |
| 99 | +fetchHomeData:(currentUserAnonymous?:boolean|undefined)=>void; |
| 100 | +fetchLowcoderCompVersions:()=>void; |
| 101 | +getCurrentUser:()=>void; |
| 102 | +favicon:string; |
| 103 | +brandName:string; |
| 104 | +uiLanguage:string; |
| 105 | +}; |
| 106 | + |
| 107 | +classAppIndexextendsReact.Component<AppIndexProps,any>{ |
| 108 | +componentDidMount(){ |
| 109 | +this.props.getCurrentUser(); |
| 110 | +// if (!this.props.currentUserAnonymous) { |
| 111 | +// this.props.fetchHomeData(this.props.currentUserAnonymous); |
| 112 | +// } |
| 113 | +} |
| 114 | +componentDidUpdate(prevProps:AppIndexProps){ |
| 115 | +if( |
| 116 | +prevProps.currentOrgId!==this.props.currentOrgId&& |
| 117 | +this.props.currentOrgId!=='' |
| 118 | +){ |
| 119 | +this.props.fetchConfig(this.props.currentOrgId); |
| 120 | +if(!this.props.currentUserAnonymous){ |
| 121 | +this.props.fetchHomeData(this.props.currentUserAnonymous); |
| 122 | +this.props.fetchLowcoderCompVersions(); |
| 123 | +} |
| 124 | +} |
| 125 | +} |
| 126 | +render(){ |
| 127 | +constisTemplate=hasQueryParam('template'); |
| 128 | +constpathname=history.location.pathname; |
| 129 | + |
| 130 | +// we check if we are on the public cloud |
| 131 | +constisLowCoderDomain=window.location.hostname==='app.lowcoder.cloud'; |
| 132 | +constisLocalhost=window.location.hostname==='localhost'; |
| 133 | + |
| 134 | +/* if (isLocalhost || isLowCoderDomain) { |
| 135 | + posthog.init('phc_lD36OXeppUehLgI33YFhioTpXqThZ5QqR8IWeKvXP7f', { api_host: 'https://eu.i.posthog.com', person_profiles: 'always' }); |
| 136 | + } */ |
| 137 | + |
| 138 | +// make sure all users in this app have checked login info |
| 139 | +if(!this.props.isFetchUserFinished||(this.props.currentUserId&&!this.props.fetchHomeDataFinished)){ |
| 140 | +consthideLoadingHeader=isTemplate||isAuthUnRequired(pathname); |
| 141 | +return<ProductLoadinghideHeader={hideLoadingHeader}/>; |
| 142 | +} |
| 143 | +else{ |
| 144 | +// if the user just logged in, we send the event to posthog |
| 145 | +if(isLocalhost||isLowCoderDomain){ |
| 146 | +if(sessionStorage.getItem('_just_logged_in_')){ |
| 147 | +// posthog.identify(this.props.currentUserId); |
| 148 | +sessionStorage.removeItem('_just_logged_in_'); |
| 149 | +} |
| 150 | +} |
| 151 | +} |
| 152 | + |
| 153 | +return( |
| 154 | +<Wrapperlanguage={this.props.uiLanguage}> |
| 155 | +<Helmet> |
| 156 | +{<title>{this.props.brandName}</title>} |
| 157 | +{<linkrel="icon"href={this.props.favicon}/>} |
| 158 | +<metaname="description"content={trans('productDesc')}/> |
| 159 | +<meta |
| 160 | +name="keywords" |
| 161 | +content="Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development" |
| 162 | +/> |
| 163 | +<metaname="author"content="Lowcoder Software LTD"/> |
| 164 | +<metaname="robots"content="index, follow"/> |
| 165 | + |
| 166 | +<meta |
| 167 | +key="og:title" |
| 168 | +property="og:title" |
| 169 | +content={this.props.brandName} |
| 170 | +/> |
| 171 | +<meta |
| 172 | +key="og:description" |
| 173 | +property="og:description" |
| 174 | +content={trans('productDesc')} |
| 175 | +/> |
| 176 | +<meta |
| 177 | +key="og:image" |
| 178 | +property="og:image" |
| 179 | +content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" |
| 180 | +/> |
| 181 | +<metakey="og:url"property="og:url"content={window.location.href}/> |
| 182 | +<metakey="og:type"property="og:type"content="website"/> |
| 183 | + |
| 184 | +<meta |
| 185 | +key="twitter:card" |
| 186 | +name="twitter:card" |
| 187 | +content="summary_large_image" |
| 188 | +/> |
| 189 | +<meta |
| 190 | +key="twitter:title" |
| 191 | +name="twitter:title" |
| 192 | +content={this.props.brandName} |
| 193 | +/> |
| 194 | +<meta |
| 195 | +key="twitter:description" |
| 196 | +name="twitter:description" |
| 197 | +content={trans('productDesc')} |
| 198 | +/> |
| 199 | +<meta |
| 200 | +key="twitter:image" |
| 201 | +name="twitter:image" |
| 202 | +content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" |
| 203 | +/> |
| 204 | + |
| 205 | +<meta |
| 206 | +key="viewport" |
| 207 | +name="viewport" |
| 208 | +content="width=device-width, initial-scale=1, shrink-to-fit=no" |
| 209 | +/> |
| 210 | +<meta |
| 211 | +key="mobile-web-app-capable" |
| 212 | +name="mobile-web-app-capable" |
| 213 | +content="yes" |
| 214 | +/> |
| 215 | +<metakey="theme-color"name="theme-color"content="#b480de"/> |
| 216 | + |
| 217 | +<meta |
| 218 | +key="apple-mobile-web-app-capable" |
| 219 | +name="apple-mobile-web-app-capable" |
| 220 | +content="yes" |
| 221 | +/> |
| 222 | +<meta |
| 223 | +key="apple-mobile-web-app-status-bar-style" |
| 224 | +name="apple-mobile-web-app-status-bar-style" |
| 225 | +content="black-translucent" |
| 226 | +/> |
| 227 | +<meta |
| 228 | +key="apple-mobile-web-app-title" |
| 229 | +name="apple-mobile-web-app-title" |
| 230 | +content={this.props.brandName} |
| 231 | +/> |
| 232 | +<link |
| 233 | +key="apple-touch-icon" |
| 234 | +rel="apple-touch-icon" |
| 235 | +href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" |
| 236 | +/> |
| 237 | +<link |
| 238 | +key="apple-touch-startup-image" |
| 239 | +rel="apple-touch-startup-image" |
| 240 | +href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" |
| 241 | +/> |
| 242 | + |
| 243 | +<meta |
| 244 | +key="application-name" |
| 245 | +name="application-name" |
| 246 | +content={this.props.brandName} |
| 247 | +/> |
| 248 | +<meta |
| 249 | +key="msapplication-TileColor" |
| 250 | +name="msapplication-TileColor" |
| 251 | +content="#b480de" |
| 252 | +/> |
| 253 | +<meta |
| 254 | +key="msapplication-TileImage" |
| 255 | +name="msapplication-TileImage" |
| 256 | +content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png" |
| 257 | +/> |
| 258 | +{/*}<meta key="msapplication-config" name="msapplication-config" content="https://www.yourdomain.com/path/to/browserconfig.xml" />, */} |
| 259 | + |
| 260 | +<linkrel="canonical"href={window.location.href}/> |
| 261 | +{isLowCoderDomain||isLocalhost&&[ |
| 262 | +// Adding Support for iframely to be able to embedd the component explorer in the docu |
| 263 | +<meta |
| 264 | +key="iframely:title" |
| 265 | +property="iframely:title" |
| 266 | +content={this.props.brandName} |
| 267 | +/>, |
| 268 | +<meta |
| 269 | +key="iframely:description" |
| 270 | +property="iframely:description" |
| 271 | +content={trans('productDesc')} |
| 272 | +/>, |
| 273 | +<link |
| 274 | +key="iframely" |
| 275 | +rel="iframely" |
| 276 | +type="text/html" |
| 277 | +href={window.location.href} |
| 278 | +media="(aspect-ratio: 1280/720)" |
| 279 | +/>, |
| 280 | + |
| 281 | +<link |
| 282 | +key="preconnect-googleapis" |
| 283 | +rel="preconnect" |
| 284 | +href="https://fonts.googleapis.com" |
| 285 | +/>, |
| 286 | +<link |
| 287 | +key="preconnect-gstatic" |
| 288 | +rel="preconnect" |
| 289 | +href="https://fonts.gstatic.com" |
| 290 | +crossOrigin="anonymous" |
| 291 | +/>, |
| 292 | +<link |
| 293 | +key="font-ubuntu" |
| 294 | +href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400&display=swap" |
| 295 | +rel="stylesheet" |
| 296 | +/>, |
| 297 | +// adding Clearbit Support for Analytics |
| 298 | +<script |
| 299 | +key="clearbit-script" |
| 300 | +src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js" |
| 301 | +referrerPolicy="strict-origin-when-cross-origin" |
| 302 | +type="text/javascript" |
| 303 | +></script>, |
| 304 | +]} |
| 305 | +</Helmet> |
| 306 | +<SystemWarning/> |
| 307 | +<Routerhistory={history}> |
| 308 | +<Switch> |
| 309 | +<LazyRoute |
| 310 | +fallback="layout" |
| 311 | +path={APP_EDITOR_URL} |
| 312 | +component={LazyAppEditor} |
| 313 | +/> |
| 314 | +</Switch> |
| 315 | +</Router> |
| 316 | +</Wrapper> |
| 317 | +); |
| 318 | +} |
| 319 | +} |
| 320 | + |
| 321 | +constAppIndexWithProps=connect(mapStateToProps,mapDispatchToProps)(AppIndex); |
| 322 | + |
| 323 | +exportfunctionbootstrap(){ |
| 324 | +initApp(); |
| 325 | +loadComps(); |
| 326 | + |
| 327 | +constcontainer=document.getElementById("root"); |
| 328 | +constroot=createRoot(container!); |
| 329 | +root.render( |
| 330 | +<Providerstore={reduxStore}> |
| 331 | +<AppIndexWithProps/> |
| 332 | +</Provider> |
| 333 | +); |
| 334 | +} |