diff --git a/frontend/src/_components/NotificationBanner/NotificationBanner.jsx b/frontend/src/_components/NotificationBanner/NotificationBanner.jsx
new file mode 100644
index 0000000000..8b61b37f1d
--- /dev/null
+++ b/frontend/src/_components/NotificationBanner/NotificationBanner.jsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import { Alert } from '@/_ui/Alert/Alert';
+import './resources/styles.scss';
+
+const DEFAULT_CONFIG = {
+ docsLink: ' https://docs.tooljet.com/docs/data-sources/local-data-sources-migration',
+};
+
+const DEFAULT_MESSAGES = {
+ prefix: 'This query is connected to a local data source which has been',
+ highlightedText: 'discontinued',
+ middle: 'Please create a global data source connection to reconnect your query.',
+ suffix: 'to know more.',
+ linkText: 'Read documentation',
+};
+
+const NotificationBanner = ({
+ docsLink,
+ customMessage,
+ darkMode = false,
+ highlightedText = DEFAULT_MESSAGES.highlightedText,
+ highlightedClassName = 'highlighted-text',
+ enhanceDisabledVisibility = false,
+}) => {
+ const currentDocsLink = docsLink || DEFAULT_CONFIG.docsLink;
+
+ const bannerMessage = customMessage || (
+ <>
+ {DEFAULT_MESSAGES.prefix}
{highlightedText}.{' '}
+ {DEFAULT_MESSAGES.middle}{' '}
+
+ {DEFAULT_MESSAGES.linkText}
+ {' '}
+ {DEFAULT_MESSAGES.suffix}
+ >
+ );
+
+ return (
+
+ );
+};
+
+export default NotificationBanner;
+
+// To Do later: Expand this component properly to make it generic notification component
diff --git a/frontend/src/_components/NotificationBanner/index.js b/frontend/src/_components/NotificationBanner/index.js
new file mode 100644
index 0000000000..e762ccced6
--- /dev/null
+++ b/frontend/src/_components/NotificationBanner/index.js
@@ -0,0 +1 @@
+export { default } from './NotificationBanner';
diff --git a/frontend/src/_components/NotificationBanner/resources/styles.scss b/frontend/src/_components/NotificationBanner/resources/styles.scss
new file mode 100644
index 0000000000..7c8d644933
--- /dev/null
+++ b/frontend/src/_components/NotificationBanner/resources/styles.scss
@@ -0,0 +1,55 @@
+.notification-banner {
+ display: flex;
+ padding: var(--3, 6px) var(--6, 12px);
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ gap: 32px;
+ flex: 1 0 0;
+ border-radius: var(--3, 6px);
+ background: var(--background-warning-weak, #FAEFE7);
+ border: none !important;
+ outline: none !important;
+ opacity: 1;
+
+ img {
+ margin-top: -5px !important;
+ }
+}
+
+@media screen and (min-width: 1200px) {
+ .notification-banner {
+ justify-content: center !important;
+ align-items: center !important;
+ }
+
+ &>div {
+ justify-content: center !important;
+ }
+
+}
+
+.notification-content {
+ color: var(--text-default, #1B1F24);
+ font-family: "IBM Plex Sans";
+ font-size: 11px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 16px;
+
+ &.disabled {
+ font-weight: 700 !important;
+ opacity: 1 !important;
+ }
+}
+
+.highlighted-text {
+ font-weight: 600 !important;
+ font-style: bold;
+}
+
+.documentation-link {
+ font-weight: 400 !important;
+ color: var(--primary, #3E63DD) !important;
+ text-decoration-line: underline !important;
+}
\ No newline at end of file
diff --git a/frontend/src/_components/OrganizationManager/CreateOrganization.jsx b/frontend/src/_components/OrganizationManager/CreateOrganization.jsx
index 82bd046ae1..ef256014dd 100644
--- a/frontend/src/_components/OrganizationManager/CreateOrganization.jsx
+++ b/frontend/src/_components/OrganizationManager/CreateOrganization.jsx
@@ -148,9 +148,9 @@ export const CreateOrganization = ({ showCreateOrg, setShowCreateOrg }) => {
setSlug({ value: defaultValue, error: '' });
const checkWorkspaceUniqueness = async () => {
+ sluginput.current.value = defaultValue;
try {
await organizationService.checkWorkspaceUniqueness(null, defaultValue);
- sluginput.current.value = defaultValue;
} catch (errResponse) {
let error = {
status: false,
diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss
index 1b145788b4..07895c1392 100644
--- a/frontend/src/_styles/theme.scss
+++ b/frontend/src/_styles/theme.scss
@@ -7864,7 +7864,7 @@ tbody {
.marketplace-page-sidebar {
height: calc(100vh - 64px);
- max-width: 288px;
+ max-width: 272px;
background-color: var(--page-default);
border-right: 1px solid var(--slate5) !important;
display: grid !important;
@@ -12830,6 +12830,11 @@ color: var(--text-default);
padding: 16px;
padding-top: 0px;
padding-bottom: 0px;
+
+ .p-3-constants{
+ padding: 1rem !important;
+ padding-left: 0px !important;
+ }
}
.card-footer {
diff --git a/server/.version b/server/.version
index 09ce5a7d5a..2ae831adb3 100644
--- a/server/.version
+++ b/server/.version
@@ -1 +1 @@
-3.0.3-ce-lts
+3.0.4-ce-lts
diff --git a/server/src/helpers/utils.helper.ts b/server/src/helpers/utils.helper.ts
index 72c64c0c37..41dde11284 100644
--- a/server/src/helpers/utils.helper.ts
+++ b/server/src/helpers/utils.helper.ts
@@ -424,3 +424,13 @@ export function mergeDeep(target, source, seen = new WeakMap()) {
return target;
}
+export const getSubpath = () => {
+ const subpath = process.env.SUB_PATH || '';
+ // Ensure subpath starts and ends with slashes
+ if (subpath) {
+ if (!subpath.startsWith('/') || !subpath.endsWith('/')) {
+ throw new Error('SUB_PATH must start and end with a slash');
+ }
+ }
+ return subpath;
+};
\ No newline at end of file
diff --git a/server/src/main.ts b/server/src/main.ts
index 0efcbbfd18..f7a129ff86 100644
--- a/server/src/main.ts
+++ b/server/src/main.ts
@@ -13,6 +13,7 @@ import { bootstrap as globalAgentBootstrap } from 'global-agent';
import { join } from 'path';
import * as helmet from 'helmet';
import * as express from 'express';
+import { getSubpath } from '@helpers/utils.helper';
const fs = require('fs');
@@ -100,7 +101,15 @@ function setSecurityHeaders(app, configService) {
app.use((req, res, next) => {
res.setHeader('Permissions-Policy', 'geolocation=(self), camera=(), microphone=()');
- res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
+
+ const subpath = getSubpath();
+ const path = req.path.replace(subpath, subpath ? '/' : '');
+ if (path.startsWith('/api/')) {
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
+ } else {
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
+ }
+
return next();
});
}