diff --git a/frontend/web/components/Announcement.tsx b/frontend/web/components/Announcement.tsx new file mode 100644 index 000000000000..291aebc53c6e --- /dev/null +++ b/frontend/web/components/Announcement.tsx @@ -0,0 +1,51 @@ +import React, { FC } from 'react' +import InfoMessage from './InfoMessage' +import flagsmith from 'flagsmith' +import Utils from 'common/utils/utils' + +export type AnnouncementValueType = { + id: string + title: string + description: string + isClosable: boolean + buttonText: string + url: string +} + +type AnnouncementType = {} + +const Announcement: FC = () => { + const closeAnnouncement = (id: string) => { + flagsmith.setTrait(`dismissed_announcement`, id) + } + + const announcementValue = Utils.getFlagsmithJSONValue('announcement', null) + const { buttonText, description, id, isClosable, title, url } = + announcementValue as AnnouncementValueType + const dismissed = flagsmith.getTrait('dismissed_announcement') + + const showBanner = + announcementValue && + (!dismissed || dismissed !== announcementValue.id) && + Utils.getFlagsmithHasFeature('announcement') + + return ( + <> + {showBanner && ( + closeAnnouncement(id)} + buttonText={buttonText} + url={url} + > +
+
{description}
+
+
+ )} + + ) +} + +export default Announcement diff --git a/frontend/web/components/AnnouncementPerPage.tsx b/frontend/web/components/AnnouncementPerPage.tsx new file mode 100644 index 000000000000..4d357df81758 --- /dev/null +++ b/frontend/web/components/AnnouncementPerPage.tsx @@ -0,0 +1,63 @@ +import React, { FC } from 'react' +import InfoMessage from './InfoMessage' +import flagsmith from 'flagsmith' +import Utils from 'common/utils/utils' +import { AnnouncementValueType } from './Announcement' +import { matchPath } from 'react-router' +import { routes } from 'web/routes' + +type AnnouncementPerPageValueType = AnnouncementValueType & { + pages: string[] +} + +type AnnouncementPerPageType = { pathname: string } + +const AnnouncementPerPage: FC = ({ pathname }) => { + const closeAnnouncement = (id: string) => { + flagsmith.setTrait(`dismissed_announcement_per_page`, id) + } + + const announcementPerPageDismissed = flagsmith.getTrait( + 'dismissed_announcement_per_page', + ) + const announcementPerPageValue = Utils.getFlagsmithJSONValue( + 'announcement_per_page', + null, + ) as AnnouncementPerPageValueType + + const showAnnouncementPerPage = + (!announcementPerPageDismissed || + announcementPerPageDismissed !== announcementPerPageValue.id) && + Utils.getFlagsmithHasFeature('announcement_per_page') && + announcementPerPageValue?.pages?.length > 0 + + const announcementInPage = announcementPerPageValue?.pages?.some((page) => { + if (Object.keys(routes).includes(page)) { + return !!matchPath(pathname, { + exact: false, + path: routes[page], + strict: false, + }) + } + return false + }) + return ( + <> + {showAnnouncementPerPage && announcementInPage && ( + closeAnnouncement(announcementPerPageValue?.id)} + buttonText={announcementPerPageValue?.buttonText} + url={announcementPerPageValue?.url} + > +
+
{announcementPerPageValue?.description}
+
+
+ )} + + ) +} + +export default AnnouncementPerPage diff --git a/frontend/web/components/App.js b/frontend/web/components/App.js index cc4bd77e9bcd..5df9a8ed880f 100644 --- a/frontend/web/components/App.js +++ b/frontend/web/components/App.js @@ -36,6 +36,8 @@ import AuditLogIcon from './svg/AuditLogIcon' import Permission from 'common/providers/Permission' import HomeAside from './pages/HomeAside' import ScrollToTop from './ScrollToTop' +import AnnouncementPerPage from './AnnouncementPerPage' +import Announcement from './Announcement' const App = class extends Component { static propTypes = { @@ -349,13 +351,6 @@ const App = class extends Component { if (document.location.href.includes('widget')) { return
{this.props.children}
} - const announcementValue = Utils.getFlagsmithJSONValue('announcement', null) - const dismissed = flagsmith.getTrait('dismissed_announcement') - const showBanner = - announcementValue && - (!dismissed || dismissed !== announcementValue.id) && - Utils.getFlagsmithHasFeature('announcement') && - this.state.showAnnouncement const isOrganisationSelect = document.location.pathname === '/organisations' const integrations = Object.keys( JSON.parse(Utils.getFlagsmithValue('integration_data') || '{}'), @@ -390,25 +385,15 @@ const App = class extends Component { } /> )} - {user && showBanner && ( + {user && (
-
- - this.closeAnnouncement(announcementValue.id) - } - buttonText={announcementValue.buttonText} - url={announcementValue.url} - > -
-
{announcementValue.description}
-
-
+
+ +
)} + {this.props.children} )} diff --git a/frontend/web/routes.js b/frontend/web/routes.js index f91b836d9044..24a113eb7645 100644 --- a/frontend/web/routes.js +++ b/frontend/web/routes.js @@ -41,172 +41,226 @@ import SDKKeysPage from './components/SDKKeysPage' import { ParameterizedRoute } from './components/base/higher-order/ParameterizedRoute' import FeatureHistoryDetailPage from './components/pages/FeatureHistoryDetailPage' +export const routes = { + 'root': '/', + 'login': '/login', + 'not-found': '/404', + 'signup': '/signup', + 'home': '/home', + 'github-setup': '/github-setup', + 'maintenance': '/maintenance', + 'password-reset': '/password-reset/confirm/:uid/:token/', + 'features': '/project/:projectId/environment/:environmentId/features', + 'change-requests': + '/project/:projectId/environment/:environmentId/change-requests', + 'scheduled-changes': + '/project/:projectId/environment/:environmentId/scheduled-changes', + 'change-request': + '/project/:projectId/environment/:environmentId/change-requests/:id', + 'scheduled-change': + '/project/:projectId/environment/:environmentId/scheduled-changes/:id', + 'widget': '/widget', + 'invite': '/invite/:id', + 'invite-link': '/invite-link/:id', + 'broken': '/broken', + 'oauth': '/oauth/:type', + 'saml': '/saml', + 'environment-settings': + '/project/:projectId/environment/:environmentId/settings', + 'sdk-keys': '/project/:projectId/environment/:environmentId/sdk-keys', + 'integrations': '/project/:projectId/integrations', + 'users': '/project/:projectId/environment/:environmentId/users', + 'user-id': '/project/:projectId/environment/:environmentId/users/:identity', + 'user': '/project/:projectId/environment/:environmentId/users/:identity/:id', + 'create-environment': '/project/:projectId/environment/create', + 'project-settings-in-environment': + '/project/:projectId/environment/:environmentId/project-settings', + 'compare': '/project/:projectId/compare', + 'feature-history': '/project/:projectId/environment/:environmentId/history', + 'feature-history-detail': + '/project/:projectId/environment/:environmentId/history/:id/', + 'project-settings': '/project/:projectId/settings', + 'permissions': '/project/:projectId/permissions', + 'segments': '/project/:projectId/segments', + 'organisation-settings': '/organisation/:organisationId/settings', + 'organisation-permissions': '/organisation/:organisationId/permissions', + 'organisation-usage': '/organisation/:organisationId/usage', + 'organisation-settings-redirect': '/organisation-settings', + 'organisation-projects': '/organisation/:organisationId/projects', + 'account-settings': '/project/:projectId/environment/:environmentId/account', + 'audit-log': '/project/:projectId/audit-log', + 'organisations': '/organisations', + 'audit-log-item': '/project/:projectId/audit-log/:id', + 'create-organisation': '/create', + 'project-redirect': '/project/:projectId', + 'account': '/account', +} export default ( - - - - - + + + + + {Utils.getFlagsmithHasFeature('github_integration') && ( - + )} - + - - - - - - + + + + + + + - + - - + - + - +