ID:
-
- {env.environmentId}
-
+ {isAccessible ? (
+
+ {env.environmentId}
+
+ ) : (
+
+ {env.environmentId}
+
+ )}
Domain:
{env.environmentFrontendUrl ? (
-
e.stopPropagation()}
- style={{ fontSize: '13px' }}
- >
- {env.environmentFrontendUrl.replace(/^https?:\/\//, '')}
-
-
+ isAccessible ? (
+
e.stopPropagation()}
+ style={{ fontSize: '13px' }}
+ >
+ {env.environmentFrontendUrl.replace(/^https?:\/\//, '')}
+
+
+ ) : (
+
+ {env.environmentFrontendUrl.replace(/^https?:\/\//, '')}
+
+ )
) : (
—
)}
From 0204bf318581889a3401e1b05505ba93745e51b9 Mon Sep 17 00:00:00 2001
From: Faran Javed
Date: Mon, 26 May 2025 23:12:05 +0500
Subject: [PATCH 06/10] Add unlicensed environemnt component for Detail page
---
.../environments/EnvironmentDetail.tsx | 42 +---
.../components/UnlicensedEnvironmentView.tsx | 215 ++++++++++++++++++
2 files changed, 223 insertions(+), 34 deletions(-)
create mode 100644 client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
diff --git a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx
index 2ef8ed31c..e038b958b 100644
--- a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx
+++ b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx
@@ -25,6 +25,7 @@ import {
import { useSingleEnvironmentContext } from "./context/SingleEnvironmentContext";
import EditEnvironmentModal from "./components/EditEnvironmentModal";
+import UnlicensedEnvironmentView from "./components/UnlicensedEnvironmentView";
import { Environment } from "./types/environment.types";
import history from "@lowcoder-ee/util/history";
import WorkspacesTab from "./components/WorkspacesTab";
@@ -100,43 +101,16 @@ const EnvironmentDetail: React.FC = () => {
);
}
- // Check if environment is not licensed and show restriction message
+ // Check if environment is not licensed and show modern UI
if (environment.isLicensed === false) {
- const getLicenseIcon = () => {
- switch (environment.licenseStatus) {
- case 'unlicensed':
- return ;
- case 'error':
- return ;
- default:
- return ;
- }
- };
-
return (
-
- history.push("/setting/environments")}
- >
- Back to Environments
- ,
-
- Edit Environment
-
- ]}
+ <>
+
- {/* Still allow editing the environment to fix license issues */}
+ {/* Edit Environment Modal */}
{environment && (
{
loading={isUpdating}
/>
)}
-
+ >
);
}
diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
new file mode 100644
index 000000000..3ed35042f
--- /dev/null
+++ b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
@@ -0,0 +1,215 @@
+import React from 'react';
+import { Button, Card, Space, Typography, Row, Col } from 'antd';
+import {
+ CustomerServiceOutlined,
+ EditOutlined,
+ ArrowLeftOutlined,
+ CloseCircleOutlined,
+ ExclamationCircleOutlined,
+ WarningOutlined
+} from '@ant-design/icons';
+import { Environment } from '../types/environment.types';
+import history from "@lowcoder-ee/util/history";
+
+const { Title, Text } = Typography;
+
+interface UnlicensedEnvironmentViewProps {
+ environment: Environment;
+ onEditClick: () => void;
+}
+
+/**
+ * Modern UI for unlicensed environments
+ */
+const UnlicensedEnvironmentView: React.FC = ({
+ environment,
+ onEditClick
+}) => {
+ const getLicenseIcon = () => {
+ switch (environment.licenseStatus) {
+ case 'unlicensed':
+ return ;
+ case 'error':
+ return ;
+ default:
+ return ;
+ }
+ };
+
+ const getLicenseTitle = () => {
+ switch (environment.licenseStatus) {
+ case 'unlicensed':
+ return 'Environment Not Licensed';
+ case 'error':
+ return 'License Configuration Error';
+ default:
+ return 'License Issue';
+ }
+ };
+
+ const getLicenseDescription = () => {
+ if (environment.licenseError) {
+ return environment.licenseError;
+ }
+
+ switch (environment.licenseStatus) {
+ case 'unlicensed':
+ return 'This environment requires a valid license to access its features and functionality.';
+ case 'error':
+ return 'There was an error validating the license for this environment. Please check the configuration.';
+ default:
+ return 'This environment has license-related issues that need to be resolved.';
+ }
+ };
+
+ return (
+
+
+
+
+ {/* Main Status Card */}
+
+ {/* Status Icon */}
+
+ {getLicenseIcon()}
+
+
+ {/* Environment Info */}
+
+
+ {getLicenseTitle()}
+
+
+ {getLicenseDescription()}
+
+
+ {/* Environment Details */}
+
+ Environment:
+
+ {environment.environmentName || 'Unnamed Environment'}
+
+
+ ID: {environment.environmentId}
+
+
+
+
+ {/* Action Buttons */}
+
+ }
+ style={{
+ width: '100%',
+ height: '48px',
+ borderRadius: '8px',
+ fontSize: '16px',
+ fontWeight: 500,
+ background: 'linear-gradient(135deg, #1890ff 0%, #0050b3 100%)',
+ border: 'none',
+ boxShadow: '0 4px 12px rgba(24, 144, 255, 0.3)'
+ }}
+ // onClick will be handled later when modal is ready
+ >
+ Contact Lowcoder Team
+
+
+ }
+ onClick={onEditClick}
+ style={{
+ width: '100%',
+ height: '48px',
+ borderRadius: '8px',
+ fontSize: '16px',
+ fontWeight: 500,
+ borderColor: '#d9d9d9',
+ color: '#595959'
+ }}
+ >
+ Edit Environment
+
+
+ }
+ onClick={() => history.push("/setting/environments")}
+ style={{
+ width: '100%',
+ height: '48px',
+ borderRadius: '8px',
+ fontSize: '16px',
+ fontWeight: 500,
+ borderColor: '#d9d9d9',
+ color: '#8c8c8c'
+ }}
+ >
+ Back to Environments
+
+
+
+
+ {/* Footer Help Text */}
+
+ Need assistance? Contact our team for licensing support or edit the environment configuration to resolve this issue.
+
+
+
+
+
+ );
+};
+
+export default UnlicensedEnvironmentView;
\ No newline at end of file
From 130b7625898c2a0563cb97497058081dc008dace Mon Sep 17 00:00:00 2001
From: Faran Javed
Date: Mon, 26 May 2025 23:25:13 +0500
Subject: [PATCH 07/10] Add contact modal for unlicense environment
---
.../components/ContactLowcoderModal.tsx | 132 ++++++++++++++++++
.../components/UnlicensedEnvironmentView.tsx | 14 +-
2 files changed, 144 insertions(+), 2 deletions(-)
create mode 100644 client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx
diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx
new file mode 100644
index 000000000..22c9ddd64
--- /dev/null
+++ b/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx
@@ -0,0 +1,132 @@
+import React, { useEffect } from 'react';
+import { Modal, Card, Row, Col, Typography, Divider } from 'antd';
+import { CustomerServiceOutlined, CloudServerOutlined } from '@ant-design/icons';
+import { useSelector, useDispatch } from 'react-redux';
+import { getDeploymentId } from 'redux/selectors/configSelectors';
+import { fetchDeploymentIdAction } from 'redux/reduxActions/configActions';
+import { Environment } from '../types/environment.types';
+
+const { Title, Text } = Typography;
+
+interface ContactLowcoderModalProps {
+ visible: boolean;
+ onClose: () => void;
+ environment: Environment;
+}
+
+/**
+ * Professional modal for contacting Lowcoder team with HubSpot form integration
+ */
+const ContactLowcoderModal: React.FC = ({
+ visible,
+ onClose,
+ environment
+}) => {
+ // Get deploymentId from Redux config provider
+ const deploymentId = useSelector(getDeploymentId);
+ const dispatch = useDispatch();
+
+ // Fetch deployment ID when modal opens if not already available
+ useEffect(() => {
+ if (visible && !deploymentId) {
+ dispatch(fetchDeploymentIdAction());
+ }
+ }, [visible, deploymentId, dispatch]);
+
+ return (
+
+
+ Contact Lowcoder Team
+
+ }
+ open={visible}
+ onCancel={onClose}
+ footer={null}
+ width={800}
+ centered
+ style={{ top: 20 }}
+ bodyStyle={{ padding: '24px' }}
+ >
+ {/* Environment Context Section */}
+
+
+
+
+
+
+
+
+ Environment: {environment.environmentName || 'Unnamed Environment'}
+
+
+
+ Environment ID: {environment.environmentId}
+
+
+
+ Deployment ID: {deploymentId || 'Loading...'}
+
+
+
+
+
+
+
+
+ {/* HubSpot Form Integration Section */}
+
+
+ Get in Touch
+
+
+
+ Our team is here to help you resolve licensing issues and get your environment up and running.
+
+
+ {/* HubSpot Form Container */}
+
+ {/* HubSpot form will be integrated here */}
+
+
+
Contact form will be integrated here
+
+
+
+ {/* Environment data is available for form pre-filling */}
+ {/* Data available: environment.environmentName, environment.environmentId, deploymentId,
+ environment.licenseStatus, environment.environmentType, environment.licenseError */}
+
+
+ );
+};
+
+export default ContactLowcoderModal;
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
index 3ed35042f..717aacde4 100644
--- a/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
+++ b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useState } from 'react';
import { Button, Card, Space, Typography, Row, Col } from 'antd';
import {
CustomerServiceOutlined,
@@ -9,6 +9,7 @@ import {
WarningOutlined
} from '@ant-design/icons';
import { Environment } from '../types/environment.types';
+import ContactLowcoderModal from './ContactLowcoderModal';
import history from "@lowcoder-ee/util/history";
const { Title, Text } = Typography;
@@ -25,6 +26,8 @@ const UnlicensedEnvironmentView: React.FC
= ({
environment,
onEditClick
}) => {
+ const [isContactModalVisible, setIsContactModalVisible] = useState(false);
+
const getLicenseIcon = () => {
switch (environment.licenseStatus) {
case 'unlicensed':
@@ -144,6 +147,7 @@ const UnlicensedEnvironmentView: React.FC = ({
type="primary"
size="large"
icon={ }
+ onClick={() => setIsContactModalVisible(true)}
style={{
width: '100%',
height: '48px',
@@ -154,7 +158,6 @@ const UnlicensedEnvironmentView: React.FC = ({
border: 'none',
boxShadow: '0 4px 12px rgba(24, 144, 255, 0.3)'
}}
- // onClick will be handled later when modal is ready
>
Contact Lowcoder Team
@@ -208,6 +211,13 @@ const UnlicensedEnvironmentView: React.FC = ({