console: add onboarding docs helper (#355)

GitOrigin-RevId: b60670a3e72b5ec27e63571779c76421b23caf3d
This commit is contained in:
Ikechukwu Eze 2021-02-01 11:08:53 +01:00 committed by hasura-bot
parent 05f21a2768
commit df19b7d654
11 changed files with 502 additions and 80 deletions

View File

@ -116,6 +116,7 @@ have select permissions to the target table of the function.
- console: allow user to cascade Postgres dependencies when dropping Postgres objects (close #5109) (#5248)
- console: mark inconsistent remote schemas in the UI (close #5093) (#5181)
- console: remove ONLY as default for ALTER TABLE in column alter operations (close #5512) #5706
- console: add onboarding helper for new users (#355)
- console: add option to flag an insertion as a migration from `Data` section (close #1766) (#4933)
- console: down migrations improvements (close #3503, #4988) (#4790)
- console: allow setting computed fields for views (close #6168) (#6174)

View File

@ -3204,7 +3204,8 @@
"@types/highlight.js": {
"version": "9.12.4",
"resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz",
"integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww=="
"integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==",
"dev": true
},
"@types/history": {
"version": "3.2.4",
@ -3272,7 +3273,8 @@
"@types/lodash": {
"version": "4.14.162",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.162.tgz",
"integrity": "sha512-alvcho1kRUnnD1Gcl4J+hK0eencvzq9rmzvFPRmP5rPHx9VVsJj6bKLTATPVf9ktgv4ujzh7T+XWKp+jhuODig=="
"integrity": "sha512-alvcho1kRUnnD1Gcl4J+hK0eencvzq9rmzvFPRmP5rPHx9VVsJj6bKLTATPVf9ktgv4ujzh7T+XWKp+jhuODig==",
"dev": true
},
"@types/lodash.merge": {
"version": "4.6.6",
@ -3550,6 +3552,15 @@
"@types/react": "*"
}
},
"@types/react-youtube": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/@types/react-youtube/-/react-youtube-7.6.2.tgz",
"integrity": "sha512-8iLihxKqRYUjZZPJrWKRpq9e407MG5dn5qq+hD4/5v92pEclhN8F1DOgbNc3hzv6d0Qc0hKLQ+rRtYpCmI1qww==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/redux-devtools": {
"version": "3.0.47",
"resolved": "https://registry.npmjs.org/@types/redux-devtools/-/redux-devtools-3.0.47.tgz",
@ -3606,6 +3617,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@types/reselect/-/reselect-2.2.0.tgz",
"integrity": "sha1-xmcgbP3DgZDh03m6vgiGWyKIV18=",
"dev": true,
"requires": {
"reselect": "*"
}
@ -3647,7 +3659,8 @@
"@types/sql-formatter": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/sql-formatter/-/sql-formatter-2.3.0.tgz",
"integrity": "sha512-Xh9kEOaKWhm3vYD5lUjYFFiSfpN4y3/iQCJUAVwFaQ1rVvHs4WXTa5C8E7gyF3kxwsMS8KgttW7WBAPtFlsvAg=="
"integrity": "sha512-Xh9kEOaKWhm3vYD5lUjYFFiSfpN4y3/iQCJUAVwFaQ1rVvHs4WXTa5C8E7gyF3kxwsMS8KgttW7WBAPtFlsvAg==",
"dev": true
},
"@types/styled-components": {
"version": "5.1.0",
@ -3793,6 +3806,12 @@
"@types/node": "*"
}
},
"@types/youtube-player": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/@types/youtube-player/-/youtube-player-5.5.3.tgz",
"integrity": "sha512-G9k9Q8fyOwzX4A8DI90WB2viYlpxDazoLZDe37GY9+82JL2OOFhEzz6yUIKEt4klACdx/UUuY0BesD68BVR7SA==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.8.0.tgz",
@ -12020,6 +12039,11 @@
}
}
},
"load-script": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
"integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ="
},
"loader-fs-cache": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
@ -15613,6 +15637,23 @@
"react-lifecycles-compat": "^3.0.4"
}
},
"react-youtube": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-7.13.0.tgz",
"integrity": "sha512-cVCQE9ktKD1NJOFcJ59jU82UgCXM4yRueWIKSRsOnBfx7uRyhgdLKPKbCQX1Xk2+iXtLpMdAjYmjgxrCvwvfqA==",
"requires": {
"fast-deep-equal": "3.1.3",
"prop-types": "15.7.2",
"youtube-player": "5.5.2"
},
"dependencies": {
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
}
}
},
"read-file-stdin": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz",
@ -16620,6 +16661,11 @@
}
}
},
"sister": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz",
"integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA=="
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@ -19010,6 +19056,31 @@
"fd-slicer": "~1.1.0"
}
},
"youtube-player": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz",
"integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==",
"requires": {
"debug": "^2.6.6",
"load-script": "^1.0.0",
"sister": "^3.0.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"zen-observable": {
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",

View File

@ -49,11 +49,6 @@
"dependencies": {
"@graphql-codegen/core": "^1.17.8",
"@graphql-codegen/typescript": "^1.17.10",
"@types/highlight.js": "9.12.4",
"@types/reselect": "^2.2.0",
"@types/lodash": "^4.14.159",
"@types/lodash.merge": "^4.6.6",
"@types/sql-formatter": "2.3.0",
"ace-builds": "^1.4.11",
"apollo-link": "1.2.14",
"apollo-link-ws": "1.0.20",
@ -93,6 +88,7 @@
"react-table": "6.11.5",
"react-tabs": "3.1.0",
"react-toggle": "4.1.1",
"react-youtube": "^7.13.0",
"redux": "4.0.5",
"redux-thunk": "2.3.0",
"reselect": "^4.0.0",
@ -104,7 +100,6 @@
"subscriptions-transport-ws": "0.9.16"
},
"devDependencies": {
"@types/jwt-decode": "2.2.1",
"@babel/core": "7.9.6",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.10.1",
@ -123,6 +118,13 @@
"@types/fork-ts-checker-webpack-plugin": "0.4.5",
"@types/isomorphic-fetch": "0.0.35",
"@types/jquery": "3.3.33",
"@types/jwt-decode": "2.2.1",
"@types/highlight.js": "9.12.4",
"@types/lodash": "^4.14.159",
"@types/lodash.merge": "^4.6.6",
"@types/react-youtube": "^7.6.2",
"@types/reselect": "^2.2.0",
"@types/sql-formatter": "2.3.0",
"@types/mini-css-extract-plugin": "0.9.1",
"@types/node-sass": "4.11.0",
"@types/optimize-css-assets-webpack-plugin": "5.0.1",
@ -152,6 +154,7 @@
"@types/webpack-dev-middleware": "3.7.0",
"@types/webpack-hot-middleware": "2.25.0",
"@types/ws": "7.2.3",
"@types/youtube-player": "^5.5.3",
"@typescript-eslint/eslint-plugin": "3.8.0",
"@typescript-eslint/parser": "2.24.0",
"autoprefixer": "9.7.6",

View File

@ -0,0 +1,109 @@
.hi_icon {
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
cursor: pointer;
text-align: center;
font-size: 24px;
width: 48px;
height: 48px;
background-color: #fff;
border-radius: 100%;
position: fixed;
bottom: 24px;
right: 24px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.08);
}
.onboarding_popup {
bottom: 32px;
z-index: 10;
right: 32px;
background: #fff;
width: 320px;
border: 1px solid #d7d7d7;
padding: 0;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.08);
position: fixed;
font-family: 'Gudea', -apple-system, sans-serif;
}
.link_icon {
float: left;
font-size: 12px;
}
.popup_header {
display: flex;
font-weight: bold;
align-items: center;
padding: 16px;
color: #4d4d4d;
background: #faca33;
font-family: 'Gudea', -apple-system, sans-serif;
}
.popup_header img {
margin-right: 8px;
width: 25px;
}
.flex_center {
display: flex;
align-items: center;
}
.popup_body ul {
list-style: none;
text-align: start;
padding: 0px;
}
.popup_item {
font-size: 16px;
border-bottom: 1px solid #cccccc;
}
.popup_item.video {
border-bottom: none;
}
.link_container {
padding: 16px;
color: inherit;
text-decoration: none;
}
.link_container.link {
display: flex;
align-items: center;
}
.link_container.link:hover {
text-decoration: underline;
i {
text-decoration: underline;
}
}
.spacer {
flex: 1;
}
.link_num {
display: inline-flex;
justify-content: center;
align-items: center;
height: 20px;
padding: 2px;
width: 20px;
background-color: #eeeeee;
border-radius: 50%;
margin-right: 8px;
}
.muted {
color: #999fb1 !important;
}
.button {
background-color: white;
border: none;
cursor: pointer;
}
.button:hover {
text-decoration: underline;
}
.popup_buttons {
display: flex;
padding: 8px 8px 16px;;
justify-content: space-between;
}

View File

@ -0,0 +1,11 @@
<svg width="155" height="160" viewBox="0 0 155 160" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M152.548 54.4799C157.147 40.1391 154.383 11.4972 145.462 0.929262C144.298 -0.453454 142.107 -0.255924 141.14 1.26506L130.147 18.5293C127.423 21.9861 122.528 22.7762 118.857 20.3663C106.936 12.5638 92.6861 8.02062 77.3703 8.02062C62.0545 8.02062 47.8045 12.5638 35.8834 20.3663C32.2124 22.7762 27.3176 21.9663 24.594 18.5293L13.6005 1.26506C12.6334 -0.255924 10.4426 -0.453454 9.27817 0.929262C0.357115 11.4972 -2.40604 40.1391 2.19264 54.4799C3.71238 59.2404 4.14659 64.2774 3.23869 69.1959C2.35054 74.0552 1.44264 79.9416 1.44264 84.0107C1.44264 125.966 35.4492 160.001 77.3703 160.001C119.311 160.001 153.298 125.986 153.298 84.0107C153.298 79.9219 152.41 74.0552 151.502 69.1959C150.594 64.2774 151.028 59.2404 152.548 54.4799ZM77.3703 143.013C44.9624 143.013 18.594 116.623 18.594 84.1885C18.594 83.1219 18.6334 82.0749 18.6729 81.028C19.8571 58.9243 33.2584 40.0206 52.2453 31.0132C59.8637 27.3786 68.39 25.3638 77.3703 25.3638C86.3505 25.3638 94.8769 27.3984 102.515 31.033C121.502 40.0404 134.903 58.9441 136.087 81.028C136.147 82.0749 136.166 83.1219 136.166 84.1885C136.147 116.623 109.778 143.013 77.3703 143.013Z" fill="#111B29"/>
<path d="M102.83 106.825L87.8101 80.7704L74.9219 59.042C74.6259 58.5284 74.0733 58.2123 73.4614 58.2123H61.1456C60.5338 58.2123 59.9812 58.5482 59.6851 59.0617C59.389 59.5951 59.389 60.2469 59.7048 60.7605L72.0206 81.5012L55.4812 106.746C55.1456 107.259 55.1062 107.931 55.4022 108.484C55.6983 109.037 56.2706 109.373 56.8825 109.373H69.2772C69.8496 109.373 70.3825 109.077 70.6983 108.602L79.639 94.6173L87.6522 108.523C87.9483 109.057 88.5206 109.373 89.1127 109.373H101.33C101.942 109.373 102.494 109.057 102.79 108.523C103.146 107.99 103.146 107.358 102.83 106.825Z" fill="#111B29"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="155" height="160" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,176 @@
import React from 'react';
import YouTube from 'react-youtube';
import globals from '../../../Globals';
import { setOnboardingCompletedInDB } from '../../../telemetry/Actions';
import { Dispatch, ReduxState } from '../../../types';
import { getLSItem, LS_KEYS, setLSItem } from '../../../utils/localStorage';
import { isMetadataEmpty } from '../../Main/utils';
import hasuraDarkIcon from './hasura_icon_dark.svg';
import styles from './Onboarding.scss';
type PopupLinkProps = {
title: string;
index: number;
link?: {
pro: string;
cloud: string;
oss: string;
};
videoId?: string;
};
const PopupLink = ({ link, index, videoId, title }: PopupLinkProps) => {
if (videoId) {
return (
<li className={`${styles.popup_item} ${styles.video}`}>
<>
<div className={styles.link_container}>
<span className={styles.link_num}>{index}</span>
{title}
</div>
<YouTube
videoId={videoId}
opts={{ width: '100%', height: '240px' }}
/>
</>
</li>
);
}
let url = link?.oss;
if (globals.serverVersion.includes('pro')) {
url = link?.pro;
} else if (globals.serverVersion.includes('cloud')) {
url = link?.cloud;
}
return (
<li className={styles.popup_item}>
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className={`${styles.link_container} ${styles.link}`}
>
<span className={styles.link_num}>{index}</span>
{title}
<div className={styles.spacer} />
<i
className={`fa fa-external-link ${styles.link_icon} ${styles.muted}`}
/>
</a>
</li>
);
};
interface OnboardingProps {
dispatch: Dispatch;
console_opts: ReduxState['telemetry']['console_opts'];
metadata: ReduxState['metadata'];
}
const Onboarding: React.FC<OnboardingProps> = ({
dispatch,
console_opts,
metadata,
}) => {
const [visible, setVisible] = React.useState(true);
const toShowOnboarding = () => {
const shown = console_opts && console_opts.onboardingShown;
if (shown) {
return false;
}
if (!metadata.metadataObject) {
return true;
}
return isMetadataEmpty(metadata.metadataObject) && !shown;
};
React.useEffect(() => {
const show = getLSItem(LS_KEYS.showConsoleOnboarding) || 'true';
setVisible(show === 'true');
}, []);
const onboardingList = [
{
title: 'Read the Getting Started Docs',
link: {
pro:
'https://hasura.io/docs/1.0/graphql/core/getting-started/first-graphql-query.html?pg=pro&plcmt=onboarding-checklist#create-a-table',
oss:
'https://hasura.io/docs/1.0/graphql/core/getting-started/first-graphql-query.html?pg=oss-console&plcmt=onboarding#create-a-table',
cloud:
'https://hasura.io/docs/1.0/graphql/core/getting-started/first-graphql-query.html?pg=cloud&plcmt=onboarding-checklist#create-a-table',
},
},
{ title: 'Watch Our Getting Started Video', videoId: 'ZGKQ0U18USU' },
{
title: 'Bookmark Our Course',
link: {
pro:
'https://hasura.io/learn/graphql/hasura-advanced/introduction/?pg=pro&plcmt=onboarding-checklist',
oss:
'https://hasura.io/learn/graphql/hasura/introduction/?pg=oss-console&plcmt=onboarding-checklist',
cloud:
'https://hasura.io/learn/graphql/hasura/introduction/?pg=cloud&plcmt=onboarding-checklist',
},
},
];
const togglePopup = () => {
setVisible(pre => {
setLSItem(LS_KEYS.showConsoleOnboarding, (!pre).toString());
return !pre;
});
};
const markCompleted = () => {
dispatch(setOnboardingCompletedInDB);
};
if (!toShowOnboarding()) {
return null;
}
return (
<>
{!visible && (
<div className={styles.hi_icon} onClick={togglePopup}>
<span aria-label="Wave" role="img">
{' '}
👋{' '}
</span>
</div>
)}
{visible && (
<div className={styles.onboarding_popup}>
<div className={styles.popup_header}>
<img src={hasuraDarkIcon} alt="Hasura Logo" />
<strong>Hi there, let&apos;s get started with Hasura!</strong>
</div>
<div className={styles.popup_body}>
<ul>
{onboardingList.map((item, i) => (
<PopupLink {...item} key={i + 1} index={i + 1} />
))}
</ul>
</div>
<div className={styles.popup_buttons}>
<button onClick={togglePopup} className={styles.button}>
Hide for now
</button>
<button
onClick={markCompleted}
className={`${styles.button} ${styles.muted}`}
>
Don&apos;t show me again
</button>
</div>
</div>
)}
</>
);
};
export default Onboarding;

View File

@ -1,49 +1,46 @@
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import * as tooltips from './Tooltips';
import { HASURA_COLLABORATOR_TOKEN } from '../../constants';
import globals from '../../Globals';
import { getPathRoot } from '../Common/utils/urlUtils';
import { versionGT } from '../../helpers/versionUtils';
import { loadInconsistentObjects } from '../../metadata/actions';
import { UPDATE_CONSOLE_NOTIFICATIONS } from '../../telemetry/Actions';
import { getLSItem, LS_KEYS, setLSItem } from '../../utils/localStorage';
import Onboarding from '../Common/Onboarding';
import Spinner from '../Common/Spinner/Spinner';
import WarningSymbol from '../Common/WarningSymbol/WarningSymbol';
import logo from './images/white-logo.svg';
import NotificationSection from './NotificationSection';
import styles from './Main.scss';
import {
loadServerVersion,
fetchServerConfig,
loadLatestServerVersion,
featureCompatibilityInit,
emitProClickedEvent,
fetchConsoleNotifications,
} from './Actions';
import {
getProClickState,
setProClickState,
getLoveConsentState,
setLoveConsentState,
getUserType,
} from './utils';
import {
getSchemaBaseRoute,
redirectToMetadataStatus,
} from '../Common/utils/routesUtils';
import LoveSection from './LoveSection';
import { getPathRoot } from '../Common/utils/urlUtils';
import WarningSymbol from '../Common/WarningSymbol/WarningSymbol';
import {
emitProClickedEvent,
featureCompatibilityInit,
fetchConsoleNotifications,
fetchServerConfig,
loadLatestServerVersion,
loadServerVersion,
} from './Actions';
import { Help, ProPopup } from './components/';
import { loadInconsistentObjects } from '../../metadata/actions';
import { HASURA_COLLABORATOR_TOKEN } from '../../constants';
import { UPDATE_CONSOLE_NOTIFICATIONS } from '../../telemetry/Actions';
import { getLSItem, LS_KEYS, setLSItem } from '../../utils/localStorage';
import { versionGT } from '../../helpers/versionUtils';
import { UpdateVersion } from './components/UpdateVersion';
import logo from './images/white-logo.svg';
import LoveSection from './LoveSection';
import styles from './Main.scss';
import NotificationSection from './NotificationSection';
import * as tooltips from './Tooltips';
import {
getLoveConsentState,
getProClickState,
getUserType,
setLoveConsentState,
setProClickState,
} from './utils';
const updateRequestHeaders = props => {
const { requestHeaders, dispatch } = props;
@ -237,7 +234,9 @@ class Main extends React.Component {
currentSchema,
serverVersion,
metadata,
console_opts,
currentSource,
dispatch,
} = this.props;
const {
@ -354,6 +353,11 @@ class Main extends React.Component {
return (
<div className={styles.container}>
<Onboarding
dispatch={dispatch}
console_opts={console_opts}
metadata={metadata}
/>
<div className={styles.flexRow}>
<div className={styles.sidebar}>
<div className={styles.header_logo_wrapper}>

View File

@ -1,8 +1,10 @@
import jwt_decode from 'jwt-decode';
import { ConsoleScope } from './ConsoleNotification';
import { Nullable } from '../Common/utils/tsUtils';
import { setLSItem, getLSItem, LS_KEYS } from '../../utils/localStorage';
import { HasuraMetadataV3 } from '../../metadata/types';
import { NotificationsState } from '../../telemetry/state';
import { getLSItem, LS_KEYS, setLSItem } from '../../utils/localStorage';
import { Nullable } from '../Common/utils/tsUtils';
import { ConsoleScope } from './ConsoleNotification';
const defaultProClickState = {
isProClicked: false,
@ -99,12 +101,21 @@ const getUserType = (token: string) => {
}
};
export {
getProClickState,
setProClickState,
setLoveConsentState,
getLoveConsentState,
getReadAllNotificationsState,
getConsoleScope,
getUserType,
const isMetadataEmpty = (metadataObject: HasuraMetadataV3) => {
const { actions, sources, remote_schemas } = metadataObject;
const hasRemoteSchema = remote_schemas && remote_schemas.length;
const hasAction = actions && actions.length;
const hasTable = sources.some(source => source.tables.length);
return !(hasRemoteSchema || hasAction || hasTable);
};
export {
getConsoleScope,
getLoveConsentState,
getProClickState,
getReadAllNotificationsState,
getUserType,
isMetadataEmpty,
setLoveConsentState,
setProClickState,
};

View File

@ -1,22 +1,23 @@
import { Dispatch, AnyAction } from 'redux';
import { AnyAction, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import Endpoints, { globalCookiePolicy } from '../Endpoints';
import requestAction from '../utils/requestAction';
import dataHeaders from '../components/Services/Data/Common/Headers';
import { getUserType } from '../components/Main/utils';
import {
showErrorNotification,
showSuccessNotification,
} from '../components/Services/Common/Notification';
import dataHeaders from '../components/Services/Data/Common/Headers';
import { HASURA_COLLABORATOR_TOKEN } from '../constants';
import Endpoints, { globalCookiePolicy } from '../Endpoints';
import globals from '../Globals';
import {
getSetConsoleStateQuery,
getConsoleStateQuery,
getSetConsoleStateQuery,
} from '../metadata/queryUtils';
import { GetReduxState, ReduxState } from '../types';
import requestAction from '../utils/requestAction';
import { ConsoleState, defaultConsoleState, NotificationsState } from './state';
import { isUpdateIDsEqual } from './utils';
import { HASURA_COLLABORATOR_TOKEN } from '../constants';
import { getUserType } from '../components/Main/utils';
import { ConsoleState, NotificationsState, defaultConsoleState } from './state';
const SET_CONSOLE_OPTS = 'Telemetry/SET_CONSOLE_OPTS';
const SET_NOTIFICATION_SHOWN = 'Telemetry/SET_NOTIFICATION_SHOWN';
@ -103,6 +104,39 @@ const setTelemetryNotificationShownInDB = () => {
return setConsoleOptsInDB(opts, successCb, errorCb);
};
const setOnboardingCompletedInDB = (
dispatch: ThunkDispatch<ReduxState, unknown, AnyAction>,
getState: GetReduxState
) => {
const successCb = () => {
dispatch(
showSuccessNotification('Success', 'Dismissed console onboarding')
);
};
const errorCb = (error: Error) => {
dispatch(
showErrorNotification(
'Failed to update console onboarding status',
null,
error
)
);
};
dispatch({
type: SET_CONSOLE_OPTS,
data: {
...getState().telemetry.console_opts,
onboardingShown: true,
},
});
return dispatch(
setConsoleOptsInDB({ onboardingShown: true }, successCb, errorCb)
);
};
type X = ReduxState['telemetry'];
const setPreReleaseNotificationOptOutInDB = () => (
@ -370,7 +404,6 @@ interface SetConsoleOptsAction {
type: typeof SET_CONSOLE_OPTS;
data: ConsoleState['console_opts'];
}
interface SetNotificationShowAction {
type: typeof SET_NOTIFICATION_SHOWN;
}
@ -442,11 +475,12 @@ const telemetryReducer = (
export default telemetryReducer;
export {
setConsoleOptsInDB,
loadConsoleOpts,
telemetryNotificationShown,
setConsoleOptsInDB,
setOnboardingCompletedInDB,
setPreReleaseNotificationOptOutInDB,
setTelemetryNotificationShownInDB,
updateConsoleNotificationsState,
telemetryNotificationShown,
UPDATE_CONSOLE_NOTIFICATIONS,
updateConsoleNotificationsState,
};

View File

@ -14,6 +14,7 @@ export type ConsoleState = {
telemetryNotificationShown?: boolean;
disablePreReleaseUpdateNotifications?: boolean;
console_notifications?: TelemetryNotificationsState;
onboardingShown?: boolean;
}>;
hasura_uuid: string;
};

View File

@ -75,26 +75,27 @@ export const listLSKeys = () => {
};
export const LS_KEYS = {
consoleAdminSecret: 'console:adminSecret',
consoleLocalInfo: `console:localInfo:${globals.dataApiUrl}`,
versionUpdateCheckLastClosed: 'console:versionUpdateCheckLastClosed',
loveConsent: 'console:loveIcon',
proClick: 'console:pro',
derivedActions: 'actions:derivedActions',
apiExplorerAdminSecretWasAdded: 'apiExplorer:adminSecretHeaderWasAdded',
apiExplorerConsoleGraphQLHeaders: 'apiExplorer:graphiqlHeaders',
apiExplorerEndpointSectionIsOpen: 'apiExplorer:endpointSectionIsOpen',
apiExplorerGraphiqlMode: 'apiExplorer:graphiQLMode',
apiExplorerHeaderSectionIsOpen: 'apiExplorer:headersSectionIsOpen',
apiExplorerAdminSecretWasAdded: 'apiExplorer:adminSecretHeaderWasAdded',
apiExplorerConsoleGraphQLHeaders: 'apiExplorer:graphiqlHeaders',
oneGraphExplorerWidth: 'graphiql:explorerWidth',
oneGraphExplorerOpen: 'graphiql:explorerOpen',
oneGraphExplorerCodeExporterOpen: 'graphiql:codeExporterOpen',
consoleAdminSecret: 'console:adminSecret',
consoleLocalInfo: `console:localInfo:${globals.dataApiUrl}`,
dataColumnsCollapsedKey: 'data:collapsed',
dataColumnsOrderKey: 'data:order',
dataPageSizeKey: 'data:pageSize',
derivedActions: 'actions:derivedActions',
graphiqlQuery: 'graphiql:query',
loveConsent: 'console:loveIcon',
oneGraphExplorerCodeExporterOpen: 'graphiql:codeExporterOpen',
oneGraphExplorerOpen: 'graphiql:explorerOpen',
oneGraphExplorerWidth: 'graphiql:explorerWidth',
proClick: 'console:pro',
rawSQLKey: 'rawSql:sql',
rawSqlStatementTimeout: 'rawSql:rawSqlStatementTimeout',
dataColumnsCollapsedKey: 'data:collapsed',
dataPageSizeKey: 'data:pageSize',
dataColumnsOrderKey: 'data:order',
showConsoleOnboarding: 'console:showConsoleOnboarding',
versionUpdateCheckLastClosed: 'console:versionUpdateCheckLastClosed',
};
export const clearGraphiqlLS = () => {