chore(ui): change github start modal to popup (#13948)

This commit is contained in:
Chirag Madlani 2023-11-13 10:26:05 +05:30 committed by GitHub
parent 294a15d9df
commit 3fdc71a98b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 313 additions and 238 deletions

View File

@ -979,6 +979,10 @@ export const login = (username, password) => {
cy.visit('/');
cy.get('[id="email"]').should('be.visible').clear().type(username);
cy.get('[id="password"]').should('be.visible').clear().type(password);
// Don't want to show any popup in the tests
cy.setCookie(`STAR_OMD_USER_${username.split('@')[0]}`, 'true');
cy.get('.ant-btn').contains('Login').should('be.visible').click();
};

View File

@ -120,6 +120,9 @@ Cypress.Commands.add('storeSession', (username, password) => {
.click();
verifyResponseStatusCode('@login', 200);
cy.url().should('not.eq', `${BASE_URL}/signin`);
// Don't want to show any popup in the tests
cy.setCookie(`STAR_OMD_USER_admin`, 'true');
});
});

View File

@ -0,0 +1,153 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Icon from '@ant-design/icons/lib/components/Icon';
import { Affix, Button, Card, Skeleton, Space, Typography } from 'antd';
import ButtonGroup from 'antd/lib/button/button-group';
import { CookieStorage } from 'cookie-storage';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link, useLocation } from 'react-router-dom';
import { ReactComponent as StarGithubIcon } from '../../assets/svg/ic-star-github.svg';
import { ReactComponent as StarIcon } from '../../assets/svg/ic-start-filled-github.svg';
import { ROUTES, STAR_OMD_USER } from '../../constants/constants';
import { OMD_REPOSITORY_LINK } from '../../constants/docs.constants';
import { getRepositoryData } from '../../rest/commonAPI';
import { getReleaseVersionExpiry } from '../../utils/WhatsNewModal.util';
import { useAuthContext } from '../Auth/AuthProviders/AuthProvider';
import { COOKIE_VERSION } from '../Modals/WhatsNewModal/whatsNewData';
import './github-star-card.style.less';
const cookieStorage = new CookieStorage();
const GithubStarCard = () => {
const { t } = useTranslation();
const location = useLocation();
const { currentUser } = useAuthContext();
const [showGithubStarPopup, setShowGithubStarPopup] = useState(false);
const [starredCount, setStarredCount] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(true);
const loggedInUserName = useMemo(() => currentUser?.name, [currentUser]);
const isWhatNewAlertVisible = useMemo(
() => cookieStorage.getItem(COOKIE_VERSION) !== 'true',
[cookieStorage]
);
const userCookieName = useMemo(
() => `${STAR_OMD_USER}_${loggedInUserName}`,
[loggedInUserName]
);
const isHomePage = useMemo(
() => location.pathname.includes(ROUTES.MY_DATA),
[location.pathname]
);
const usernameExistsInCookie = useMemo(
() => Boolean(cookieStorage.getItem(userCookieName)),
[userCookieName]
);
const fetchOpenMetaData = async () => {
try {
const res = await getRepositoryData();
setStarredCount(res.stargazers_count);
} catch (err) {
// Error
} finally {
setIsLoading(false);
}
};
const updateGithubPopup = useCallback(
(show: boolean) => {
if (loggedInUserName && show) {
fetchOpenMetaData();
cookieStorage.setItem(userCookieName, 'true', {
expires: getReleaseVersionExpiry(),
});
}
setShowGithubStarPopup(show);
},
[
loggedInUserName,
usernameExistsInCookie,
userCookieName,
getReleaseVersionExpiry,
]
);
useEffect(() => {
updateGithubPopup(!usernameExistsInCookie);
return () => setShowGithubStarPopup(false);
}, [usernameExistsInCookie, updateGithubPopup]);
return showGithubStarPopup && isHomePage ? (
<Affix
className={`github-star-popup-card
${
isWhatNewAlertVisible
? 'github-star-popup-card-with-alert'
: 'github-star-popup-card-without-alert'
}
`}>
<Card data-testid="github-star-popup-card">
<Space>
<StarIcon className="github-star-icon" />
<Typography.Text className="github-star-popup-header">
{t('label.star-us-on-github')}
</Typography.Text>
</Space>
<Typography.Paragraph className="github-star-popup-description">
{t('message.star-on-github-description')}
</Typography.Paragraph>
<ButtonGroup className="github-action-button-group">
<Link
component={Typography.Link}
target="_blank"
to={{
pathname: OMD_REPOSITORY_LINK,
}}>
<Button
className="github-star-button github-modal-action-button"
icon={<Icon component={StarGithubIcon} size={12} />}>
{t('label.star')}
</Button>
</Link>
<Link
component={Typography.Link}
target="_blank"
to={{
pathname: OMD_REPOSITORY_LINK,
}}>
<Button className="github-modal-action-button">
{isLoading ? (
<Skeleton.Button active size="small" />
) : (
starredCount
)}
</Button>
</Link>
</ButtonGroup>
</Card>
</Affix>
) : null;
};
export default GithubStarCard;

View File

@ -0,0 +1,101 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import (reference) url('../../styles/variables.less');
.github-star-popup-card {
border: none;
text-align: center;
position: fixed;
right: 30px;
bottom: -100%;
z-index: 1;
background: #fff;
.ant-card {
position: relative;
width: 342px;
overflow: hidden;
border-radius: 14px;
box-shadow: @box-shadow-base;
}
.github-star-icon {
width: 24px;
vertical-align: sub;
color: @yellow-2;
}
.github-star-popup-header {
color: @primary-color;
font-size: 20px;
font-weight: 500;
}
.github-star-popup-description {
margin-top: 10px;
color: @text-grey-muted;
font-size: 14px;
font-weight: 400;
}
.github-action-button-group {
border-radius: 4px;
border: @global-border;
overflow: hidden;
.github-modal-action-button {
border: none;
&:hover {
color: initial;
border: none;
}
&:focus {
color: initial;
border: none;
}
}
.github-star-button {
background: linear-gradient(0.5turn, rgba(0, 0, 0, 0.2), transparent);
border-right: @global-border;
&:hover {
border-right: @global-border;
}
}
}
}
.github-star-popup-card-with-alert {
animation: scrollInWithAlert 2s normal forwards ease-in-out;
animation-delay: 1s;
}
.github-star-popup-card-without-alert {
animation: scrollInWithoutAlert 2s normal forwards ease-in-out;
animation-delay: 1s;
}
@keyframes scrollInWithAlert {
to {
bottom: 200px;
}
}
@keyframes scrollInWithoutAlert {
to {
bottom: 24px;
}
}

View File

@ -1,168 +0,0 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Card, Modal, Skeleton, Typography } from 'antd';
import { CookieStorage } from 'cookie-storage';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link, useLocation } from 'react-router-dom';
import { ReactComponent as CloseIcon } from '../../../assets/svg/close.svg';
import { ReactComponent as StarGithubIcon } from '../../../assets/svg/ic-star-github.svg';
import { ReactComponent as StarIcon } from '../../../assets/svg/ic-start-filled-github.svg';
import Icon from '@ant-design/icons/lib/components/Icon';
import ButtonGroup from 'antd/lib/button/button-group';
import {
ROUTES,
STAR_OMD_USER,
TEXT_GREY_MUTED,
} from '../../../constants/constants';
import { getRepositoryData } from '../../../rest/commonAPI';
import { getReleaseVersionExpiry } from '../../../utils/WhatsNewModal.util';
import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider';
import './github-star-modal.style.less';
const cookieStorage = new CookieStorage();
const GithubStarModal = () => {
const { t } = useTranslation();
const location = useLocation();
const { currentUser } = useAuthContext();
const [showGithubStarPopup, setShowGithubStarPopup] = useState(false);
const [starredCount, setStarredCount] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(true);
const loggedInUserName = useMemo(() => currentUser?.name, [currentUser]);
const userCookieName = useMemo(
() => `${STAR_OMD_USER}_${loggedInUserName}`,
[loggedInUserName]
);
const isHomePage = useMemo(
() => location.pathname.includes(ROUTES.MY_DATA),
[location.pathname]
);
const usernameExistsInCookie = useMemo(
() => Boolean(cookieStorage.getItem(userCookieName)),
[userCookieName]
);
const fetchOpenMetaData = async () => {
try {
const res = await getRepositoryData();
setStarredCount(res.stargazers_count);
} catch (err) {
// Error
} finally {
setIsLoading(false);
}
};
const updateGithubPopup = useCallback(
(show: boolean) => {
if (loggedInUserName && show) {
fetchOpenMetaData();
cookieStorage.setItem(userCookieName, 'true', {
expires: getReleaseVersionExpiry(),
});
}
setShowGithubStarPopup(show);
},
[
loggedInUserName,
usernameExistsInCookie,
userCookieName,
getReleaseVersionExpiry,
]
);
useEffect(() => {
updateGithubPopup(!usernameExistsInCookie);
return () => setShowGithubStarPopup(false);
}, [usernameExistsInCookie, updateGithubPopup]);
return (
<>
{showGithubStarPopup && isHomePage && (
<Modal
centered
destroyOnClose
keyboard
open
className="github-star-popup-modal"
closeIcon={
<CloseIcon
color={TEXT_GREY_MUTED}
data-testid="github-star-popup-close-button"
height={12}
width={12}
onClick={() => setShowGithubStarPopup(false)}
/>
}
data-testid="github-star-popup-modal"
footer={null}
maskClosable={false}
width={440}
onCancel={() => setShowGithubStarPopup(false)}>
<Card
className="github-star-popup-card"
data-testid="github-star-popup-card">
<StarIcon className="github-star-icon" />
<Typography.Text className="github-star-popup-header">
{t('label.star-us-on-github')}
</Typography.Text>
<Typography.Paragraph className="github-star-popup-description">
{t('message.star-on-github-description')}
</Typography.Paragraph>
<ButtonGroup className="github-action-button-group">
<Link
component={Typography.Link}
target="_blank"
to={{
pathname: 'https://github.com/open-metadata/OpenMetadata',
}}>
<Button
className="github-star-button github-modal-action-button"
icon={<Icon component={StarGithubIcon} size={12} />}>
{t('label.star')}
</Button>
</Link>
<Link
component={Typography.Link}
target="_blank"
to={{
pathname: 'https://github.com/open-metadata/OpenMetadata',
}}>
<Button className="github-modal-action-button">
{isLoading ? (
<Skeleton.Button active size="small" />
) : (
starredCount
)}
</Button>
</Link>
</ButtonGroup>
</Card>
</Modal>
)}
</>
);
};
export default GithubStarModal;

View File

@ -1,65 +0,0 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import (reference) url('../../../styles/variables.less');
.github-star-popup-modal {
.github-star-popup-card {
border: none;
text-align: center;
.github-star-icon {
display: block;
margin: 24px auto;
width: 50px;
color: @yellow-2;
}
.github-star-popup-header {
color: @primary-color;
font-size: 20px;
font-weight: 500;
}
.github-star-popup-description {
margin-top: 10px;
color: @text-grey-muted;
font-size: 14px;
font-weight: 400;
}
.github-action-button-group {
border-radius: 4px;
border: @global-border;
overflow: hidden;
.github-star-button {
background: linear-gradient(0.5turn, rgba(0, 0, 0, 0.2), transparent);
border-right: @global-border !important;
}
.github-modal-action-button {
border: none;
&:hover {
color: initial;
border: none;
}
&:focus {
color: initial;
border: none;
}
}
}
}
}

View File

@ -21,6 +21,7 @@ import { ReactComponent as RightArrowIcon } from '../../../../assets/svg/ic-arro
import { ReactComponent as PlayIcon } from '../../../../assets/svg/ic-play-button.svg';
import { ReactComponent as StarIcon } from '../../../../assets/svg/ic-star.svg';
import { BLACK_COLOR, ROUTES } from '../../../../constants/constants';
import { OMD_REPOSITORY_LINK } from '../../../../constants/docs.constants';
import { useAuth } from '../../../../hooks/authHooks';
import { getReleaseVersionExpiry } from '../../../../utils/WhatsNewModal.util';
import { COOKIE_VERSION, LATEST_VERSION_ID, WHATS_NEW } from '../whatsNewData';
@ -123,7 +124,7 @@ const WhatsNewAlert = () => {
component={Typography.Link}
target="_blank"
to={{
pathname: 'https://github.com/open-metadata/OpenMetadata',
pathname: OMD_REPOSITORY_LINK,
}}>
{t('label.star-open-metadata')}
</Link>

View File

@ -74,14 +74,13 @@ import BrandImage from '../common/BrandImage/BrandImage';
import CmdKIcon from '../common/CmdKIcon/CmdKIcon.component';
import { useDomainProvider } from '../Domain/DomainProvider/DomainProvider';
import { useGlobalSearchProvider } from '../GlobalSearchProvider/GlobalSearchProvider';
import GithubStarModal from '../Modals/GithubStarModal/GithubStarModal.component';
import WhatsNewAlert from '../Modals/WhatsNewModal/WhatsNewAlert/WhatsNewAlert.component';
import WhatsNewModal from '../Modals/WhatsNewModal/WhatsNewModal';
import NotificationBox from '../NotificationBox/NotificationBox.component';
import { UserProfileIcon } from '../Users/UserProfileIcon/UserProfileIcon.component';
import { useWebSocketConnector } from '../WebSocketProvider/WebSocketProvider';
import './nav-bar.less';
import { NavBarProps } from './NavBar.interface';
import popupAlertsCardsClassBase from './PopupAlertClassBase';
const cookieStorage = new CookieStorage();
@ -120,6 +119,16 @@ const NavBar = ({
useState<boolean>(false);
const [activeTab, setActiveTab] = useState<string>('Task');
const renderAlertCards = useMemo(() => {
const cardList = popupAlertsCardsClassBase.alertsCards();
return cardList.map(({ key, component }) => {
const Component = component;
return <Component key={key} />;
});
}, []);
const entitiesSelect = useMemo(
() => (
<Select
@ -519,9 +528,8 @@ const NavBar = ({
visible={isFeatureModalOpen}
onCancel={handleModalCancel}
/>
<WhatsNewAlert />
<GithubStarModal />
{renderAlertCards}
</>
);
};

View File

@ -0,0 +1,35 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import GithubStarCard from '../GithubStarCard/GithubStarCard.component';
import WhatsNewAlert from '../Modals/WhatsNewModal/WhatsNewAlert/WhatsNewAlert.component';
class PopupAlertsCardsClassBase {
public alertsCards() {
return [
{
key: 'whatNewAlertCard',
component: WhatsNewAlert,
},
{
key: 'githubPopupAlertCard',
component: GithubStarCard,
},
];
}
}
const popupAlertsCardsClassBase = new PopupAlertsCardsClassBase();
export default popupAlertsCardsClassBase;
export { PopupAlertsCardsClassBase };

View File

@ -11,6 +11,9 @@
* limitations under the License.
*/
export const OMD_REPOSITORY_LINK =
'https://github.com/open-metadata/OpenMetadata';
export const WORKFLOWS_PROFILER_DOCS =
'https://docs.open-metadata.org/connectors/ingestion/workflows/profiler';