mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 09:22:43 +03:00
console: UI fixes for neon banner in connect db page
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6376 Co-authored-by: Rishichandra Wawhal <27274869+wawhal@users.noreply.github.com> GitOrigin-RevId: 8f2ec961be370097b48b684211606d34dbaa002d
This commit is contained in:
parent
aa70c62bdd
commit
49a2822dbe
@ -6,16 +6,16 @@ export function HerokuBanner() {
|
||||
<div className="flex items-center">
|
||||
<GrHeroku size={15} className="mr-xs" color="#430098" />
|
||||
<div className="text-sm text-gray-700">
|
||||
Heroku free database integration support has been deprecated.
|
||||
</div>
|
||||
Heroku free database integration support has been deprecated.{' '}
|
||||
<a
|
||||
href="https://hasura.io/docs/latest/databases/connect-db/cloud-databases/heroku/"
|
||||
className="ml-xs font-normal text-secondary italic text-sm"
|
||||
className="text-secondary italic"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
(Know More)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -40,9 +40,6 @@ export function NeonBanner(props: Props) {
|
||||
<span className="ml-xs font-semibold flex items-center text-sm py-0.5 px-1.5 text-indigo-600 bg-indigo-100 rounded">
|
||||
Free
|
||||
</span>
|
||||
<span className="ml-xs font-semibold flex items-center text-sm py-0.5 px-1.5 text-indigo-600 bg-indigo-100 rounded">
|
||||
Preview
|
||||
</span>
|
||||
</div>
|
||||
<img
|
||||
src="https://storage.googleapis.com/graphql-engine-cdn.hasura.io/cloud-console/assets/common/img/neon.jpg"
|
||||
@ -54,8 +51,9 @@ export function NeonBanner(props: Props) {
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-sm">
|
||||
<div className="w-[70%] text-md text-gray-700">
|
||||
Fully managed Postgres with separate storage and compute, that scales
|
||||
to zero on inactivity and provides seamless scaling and branching.
|
||||
Modern, developer-friendly Postgres built for the cloud. Neon
|
||||
separates storage and compute to offer scale to zero and support
|
||||
database branching.
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
|
@ -16,11 +16,11 @@ export function Neon(props: { allDatabases: string[]; dispatch: Dispatch }) {
|
||||
|
||||
// success callback
|
||||
const pushToDatasource = (dataSourceName: string) => {
|
||||
// on success, refetch queries to show neon onboarding link in connect database page,
|
||||
// on success, refetch queries to show neon dashboard link in connect database page,
|
||||
// overriding the stale time
|
||||
reactQueryClient.refetchQueries(FETCH_NEON_PROJECTS_BY_PROJECTID_QUERYKEY);
|
||||
|
||||
dispatch(_push(`/data/${dataSourceName}`));
|
||||
dispatch(_push(`/data/${dataSourceName}/schema/public`));
|
||||
};
|
||||
const pushToConnectDBPage = () => {
|
||||
dispatch(_push(`/data/manage/connect`));
|
||||
|
@ -52,7 +52,7 @@ export function NeonOnboarding(props: {
|
||||
const neonIntegrationStatus = useNeonIntegration(
|
||||
'default',
|
||||
() => {
|
||||
// on success, refetch queries to show neon onboarding link in connect database page,
|
||||
// on success, refetch queries to show neon dashboard link in connect database page,
|
||||
// overriding the stale time
|
||||
reactQueryClient.refetchQueries(
|
||||
FETCH_NEON_PROJECTS_BY_PROJECTID_QUERYKEY
|
||||
|
@ -30,8 +30,8 @@ export const NEON_ONBOARDING_QUERY_KEY = 'neonOnboarding';
|
||||
export const experimentId = growthExperimentsIds.onboardingWizardV1;
|
||||
|
||||
export const graphQlMutation = `
|
||||
mutation trackExperimentsCohortActivity ($projectId: uuid!, $experimentId: String!, $kind: String!) {
|
||||
trackExperimentsCohortActivity(experiment: $experimentId, payload: {kind: $kind, project_id: $projectId}) {
|
||||
mutation trackExperimentsCohortActivity ($projectId: uuid!, $experimentId: String!, $kind: String! $error_code: String) {
|
||||
trackExperimentsCohortActivity(experiment: $experimentId, payload: {kind: $kind, project_id: $projectId, error_code: $error_code}) {
|
||||
status
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ import {
|
||||
type HasuraFamiliaritySurveyProps = {
|
||||
data: { question: string; options: IconCardGroupItem<string>[] };
|
||||
onOptionClick: (optionValue: string) => void;
|
||||
onSkip: () => void;
|
||||
onSkip?: () => void;
|
||||
};
|
||||
export function HasuraFamiliaritySurvey(props: HasuraFamiliaritySurveyProps) {
|
||||
const { data, onOptionClick, onSkip } = props;
|
||||
const { data, onOptionClick } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -24,14 +24,15 @@ export function HasuraFamiliaritySurvey(props: HasuraFamiliaritySurveyProps) {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cursor-pointer text-secondary text-sm hover:text-secondary-dark">
|
||||
{/* Remove skipping survey button, this change is experimental according to analytics data, so only commenting the code */}
|
||||
{/* <div className="cursor-pointer text-secondary text-sm hover:text-secondary-dark">
|
||||
<div
|
||||
data-trackid="hasura-familiarity-survey-skip-button"
|
||||
onClick={onSkip}
|
||||
>
|
||||
Skip
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||
import { APIError } from '@/hooks/error';
|
||||
import { IconCardGroupItem } from '@/new-components/IconCardGroup';
|
||||
@ -40,14 +40,19 @@ export function useFamiliaritySurveyData(): {
|
||||
},
|
||||
});
|
||||
|
||||
if (isLoading || isError) {
|
||||
return emptySurveyResponseData;
|
||||
}
|
||||
|
||||
const surveyQuestionData = data?.data?.survey?.find(
|
||||
surveyInfo => surveyInfo.survey_name === surveyName
|
||||
)?.survey_questions?.[0];
|
||||
|
||||
const surveyOptions = useMemo(
|
||||
() => mapOptionLabelToDetails(surveyQuestionData),
|
||||
[surveyQuestionData]
|
||||
);
|
||||
|
||||
if (isLoading || isError) {
|
||||
return emptySurveyResponseData;
|
||||
}
|
||||
|
||||
// skip showing the survey form if survey has no questions
|
||||
if (!surveyQuestionData) {
|
||||
return emptySurveyResponseData;
|
||||
@ -92,7 +97,7 @@ export function useFamiliaritySurveyData(): {
|
||||
showFamiliaritySurvey,
|
||||
data: {
|
||||
question: surveyQuestionData.question,
|
||||
options: mapOptionLabelToDetails(surveyQuestionData),
|
||||
options: surveyOptions,
|
||||
},
|
||||
onSkip,
|
||||
onOptionClick,
|
||||
|
@ -6,14 +6,61 @@ import {
|
||||
getFamiliaritySurveyOptionDetails,
|
||||
} from './familiaritySurveyOptionDetails';
|
||||
|
||||
export const mapOptionLabelToDetails = (
|
||||
data: SurveysResponseData['data']['survey'][0]['survey_questions'][0]
|
||||
): IconCardGroupItem<string>[] => {
|
||||
const unroderedOptionArray: {
|
||||
type UnroderedOptionArray = {
|
||||
option: FamiliaritySurveyOptionCode;
|
||||
id: string;
|
||||
}[] = [];
|
||||
data.survey_question_options.forEach(optionData => {
|
||||
}[];
|
||||
|
||||
/**
|
||||
* Manually enforces the order of options as present in `familiaritySurveyOptionCode`
|
||||
* array.
|
||||
*/
|
||||
// Not removing this function. Although it is not being used currenty due to dynamic product requirements,
|
||||
// but can again be used in future.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const manuallyOrderOptions = (unroderedOptionArray: UnroderedOptionArray) => {
|
||||
const surveyOptionDetails: IconCardGroupItem<string>[] = [];
|
||||
familiaritySurveyOptionCode.forEach(optionCode => {
|
||||
const optionData = unroderedOptionArray.find(
|
||||
optionObj => optionObj.option === optionCode
|
||||
);
|
||||
if (optionData) {
|
||||
const optionValues = getFamiliaritySurveyOptionDetails(
|
||||
optionData.id,
|
||||
optionCode
|
||||
);
|
||||
surveyOptionDetails.push(optionValues);
|
||||
}
|
||||
});
|
||||
return surveyOptionDetails;
|
||||
};
|
||||
|
||||
/**
|
||||
* Randomly shuffles order of options of survey.
|
||||
* The method comes from this algorithm: https://stackoverflow.com/a/46545530/7088648
|
||||
*/
|
||||
const randomlyOrderOptions = (unroderedOptionArray: UnroderedOptionArray) => {
|
||||
const shuffledOptionArray = unroderedOptionArray
|
||||
.map(value => ({ value, sort: Math.random() }))
|
||||
.sort((a, b) => a.sort - b.sort)
|
||||
.map(({ value }) => value);
|
||||
|
||||
const surveyOptionDetails: IconCardGroupItem<string>[] =
|
||||
shuffledOptionArray.map(option =>
|
||||
getFamiliaritySurveyOptionDetails(option.id, option.option)
|
||||
);
|
||||
|
||||
return surveyOptionDetails;
|
||||
};
|
||||
|
||||
export const mapOptionLabelToDetails = (
|
||||
data?: SurveysResponseData['data']['survey'][0]['survey_questions'][0]
|
||||
): IconCardGroupItem<string>[] => {
|
||||
if (!data) return [];
|
||||
|
||||
// Array containing order of options as it comes from backend
|
||||
const unroderedOptionArray: UnroderedOptionArray = [];
|
||||
data?.survey_question_options?.forEach(optionData => {
|
||||
const optionLabel = optionData.option.toLowerCase();
|
||||
|
||||
if (
|
||||
@ -34,20 +81,6 @@ export const mapOptionLabelToDetails = (
|
||||
});
|
||||
});
|
||||
|
||||
// enforce order of options to show in the UI
|
||||
const surveyOptionDetails: IconCardGroupItem<string>[] = [];
|
||||
familiaritySurveyOptionCode.forEach(optionCode => {
|
||||
const optionData = unroderedOptionArray.find(
|
||||
optionObj => optionObj.option === optionCode
|
||||
);
|
||||
if (optionData) {
|
||||
const optionValues = getFamiliaritySurveyOptionDetails(
|
||||
optionData.id,
|
||||
optionCode
|
||||
);
|
||||
surveyOptionDetails.push(optionValues);
|
||||
}
|
||||
});
|
||||
|
||||
return surveyOptionDetails;
|
||||
// return manuallyOrderOptions(unroderedOptionArray);
|
||||
return randomlyOrderOptions(unroderedOptionArray);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user