Skip to content
This repository has been archived by the owner on Feb 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #62 from scale8/ingest-wizard-ui
Browse files Browse the repository at this point in the history
Ingest wizard UI
  • Loading branch information
a-barzanti authored Apr 10, 2022
2 parents 8b43858 + 10358eb commit 2e62424
Show file tree
Hide file tree
Showing 26 changed files with 151 additions and 100 deletions.
1 change: 0 additions & 1 deletion api/src/enums/IngestSchemaWizard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export enum IngestSchemaWizard {
EMPTY = 'EMPTY',
USER_TRACKING = 'USER_TRACKING',
ERROR_TRACKING = 'ERROR_TRACKING',
}
33 changes: 33 additions & 0 deletions ui/src/components/atoms/FormWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FC } from 'react';
import { Box } from '@mui/material';
import WarningIcon from '@mui/icons-material/Warning';

type FormWarningProps = {
warning: string;
};

const FormWarning: FC<FormWarningProps> = ({ warning }) => {
return (
<Box
component="small"
sx={{
display: 'flex',
alignItems: 'center',
color: (theme) => theme.palette.error.main,
width: '100%',
margin: (theme) => theme.spacing(0, 0, 3),
}}
>
<WarningIcon
sx={{
backgroundColor: 'transparent',
color: (theme) => theme.palette.error.main,
margin: '3px',
}}
/>
<Box pt="2px">{warning}</Box>
</Box>
);
};

export default FormWarning;
15 changes: 10 additions & 5 deletions ui/src/components/atoms/IngestEndpointInstallInstructionCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ var fs = require('fs');
var payload = '[payloadJs]';
var reqOptions = {
'method': 'POST',
'hostname': '[domain]',[portOption][pathOption]
'hostname': '[hostname]',[portOption][pathOption]
'headers': {
'Content-Type': 'application/json'
},
Expand Down Expand Up @@ -268,12 +268,17 @@ const IngestEndpointInstallInstructionCode: FC<IngestEndpointInstallInstructionC
const payloadJs = payloadPhp;
const payloadShell = JSON.stringify(props.payload, null, 2).replace(/'/g, "'\\''");

const endpointParsedUrl = new URL(props.endpoint);
const hostname = endpointParsedUrl.hostname;
const port = endpointParsedUrl.port;
const path = endpointParsedUrl.pathname;

const text = props.snippet.snippet
.replace('[endpoint]', props.endpoint)
.replace('[domain]', props.domain)
.replace('[portOption]', props.port === '' ? '' : `\n 'port': ${props.port},`)
.replace('[pathOption]', props.path === '' ? '' : `\n 'path': '${props.path}',`)
.replace('[portParameter]', props.port === '' ? '' : `, ${props.port}`)
.replace('[hostname]', hostname)
.replace('[portOption]', port === '' ? '' : `\n 'port': ${port},`)
.replace('[pathOption]', path === '' ? '' : `\n 'path': '${path}',`)
.replace('[portParameter]', port === '' ? '' : `, ${port}`)
.replace('[payloadRuby]', payloadRuby)
.replace('[payloadPython]', payloadPython)
.replace('[payloadPhp]', payloadPhp)
Expand Down
1 change: 1 addition & 0 deletions ui/src/components/atoms/InputTypes/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const DateInput: FC<DateInputProps> = ({
minWidth: '200px',
...(sx ?? {}),
}}
variant="standard"
name={name}
/>
),
Expand Down
35 changes: 5 additions & 30 deletions ui/src/components/molecules/IngestEndpointInstallInstructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import {
ingestEndpointInstallSnippets,
} from '../atoms/IngestEndpointInstallInstructionCode';
import { Mode } from '../../gql/generated/globalTypes';
import { getNodeEnv } from '../../utils/ConfigUtils';

export type IngestEndpointInstallInstructionsDialogProps = {
installDomain: string;
installEndpoint: string;
cname: string;
payload: DataMapsPayload;
mode: Mode;
Expand All @@ -28,9 +28,6 @@ export type IngestEndpointInstallInstructionsDialogProps = {

export type IngestEndpointInstallInstructionCodeProps = {
endpoint: string;
domain: string;
port: string;
path: string;
payload: DataMapsPayload;
snippet: IngestEndpointInstallSnippet;
};
Expand All @@ -51,27 +48,6 @@ const IngestEndpointInstallInstructions: FC<IngestEndpointInstallInstructionsDia
setSnippetId(event.target.value as string);
};

const domain =
props.mode === Mode.COMMERCIAL
? `https://${props.installDomain}`
: `${window.location.protocol}//${window.location.hostname}`;

const path = props.mode === Mode.COMMERCIAL ? undefined : `/edge/${props.environmentId}`;

const determinePort = () => {
if (props.mode === Mode.COMMERCIAL) {
if (getNodeEnv() === 'development') {
return '8443';
}
return undefined;
}
return window.location.port;
};

const port = determinePort();

const endpoint = `${domain}${port === undefined ? '' : `:${port}`}${path ?? ''}`;

const currentSnippet = ingestEndpointInstallSnippets.find((_) => _.id === snippetId);

return (
Expand Down Expand Up @@ -109,7 +85,9 @@ const IngestEndpointInstallInstructions: FC<IngestEndpointInstallInstructionsDia
{tab === 'pixel' && (
<Box fontSize={12} mt={3} pb={2}>
<CopyBlock
text={`<!-- S8 Pixel -->\n<img width=0 height=0 src="${endpoint}/?d=${encodeURI(
text={`<!-- S8 Pixel -->\n<img width=0 height=0 src="${
props.installEndpoint
}/?d=${encodeURI(
JSON.stringify(props.payload),
)}" alt=""/>\n<!-- / S8 Pixel -->`}
language="html"
Expand Down Expand Up @@ -153,10 +131,7 @@ const IngestEndpointInstallInstructions: FC<IngestEndpointInstallInstructionsDia
</FormControl>
{currentSnippet !== undefined && (
<IngestEndpointInstallInstructionCode
domain={domain}
port={port ?? ''}
path={path ?? ''}
endpoint={endpoint}
endpoint={props.installEndpoint}
payload={props.payload}
snippet={currentSnippet}
/>
Expand Down
10 changes: 2 additions & 8 deletions ui/src/components/molecules/IngestEndpointPayloadInputType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { AppPlatformRevision } from '../../types/TagRulesTypes';
import { Box } from '@mui/material';
import { SelectValueWithSub } from '../../hooks/form/useFormValidation';
import FormWarning from '../atoms/FormWarning';

type SelectIngestEndpointProps = {
ingestEndpointId: string;
Expand Down Expand Up @@ -85,14 +86,7 @@ const SelectIngestEndpointEnvironment: FC<SelectIngestEndpointEnvironmentProps>
}

if (availableEnvironments.length === 0) {
return (
<Box
component="small"
sx={{ width: '100%', margin: (theme) => theme.spacing(0, 0, 3) }}
>
There are no environments defined for this endpoint.
</Box>
);
return <FormWarning warning="There are no environments defined for this endpoint." />;
}

return (
Expand Down
29 changes: 2 additions & 27 deletions ui/src/components/organisms/EnvironmentInstallInstructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import CheckBoxInput from '../atoms/InputTypes/CheckBoxInput';
import CopyBlock from '../atoms/CopyBlock';
import { buildTagInstallMarkup } from '../../utils/TextUtils';
import { Mode } from '../../gql/generated/globalTypes';
import { getNodeEnv } from '../../utils/ConfigUtils';

export type InstallInstructionsProps = {
installDomain: string;
environmentName: string;
environmentId: string;
installEndpoint: string;
mode: Mode;
cname: string;
tags: { name: string; code: string; type: string }[];
Expand All @@ -24,31 +24,6 @@ const EnvironmentInstallInstructions: FC<InstallInstructionsProps> = (
const [spaSupport, setSpaSupport] = useState(false);
const [hashSupport, setHashSupport] = useState(false);

const domain =
props.mode === Mode.COMMERCIAL
? `https://${props.installDomain}`
: `${window.location.protocol}//${window.location.hostname}`;

const path = props.mode === Mode.COMMERCIAL ? undefined : `/edge/${props.environmentId}`;

const getPort = (): number | undefined => {
if (window.location.port === '80' || window.location.port === '443') {
return undefined;
} else if (props.mode === Mode.COMMERCIAL && getNodeEnv() === 'development') {
return 8443;
} else if (getNodeEnv() === 'development') {
return 6080;
} else if (props.mode === Mode.SELF_HOSTED && getNodeEnv() === 'production') {
return +window.location.port;
} else {
return undefined;
}
};

const port = getPort();

const environmentInstallSrc = `${domain}${port === undefined ? '' : `:${port}`}${path ?? ''}`;

const script = type === 'Tag Manager' ? 'tm.js' : 'analytics.js';

const opts =
Expand All @@ -63,7 +38,7 @@ const EnvironmentInstallInstructions: FC<InstallInstructionsProps> = (
const commentOpen = `<!-- Scale8 Tag Manager${commentAnalytics}${commentEnvironment} -->\n`;
const commentClose = `\n<!-- / Scale8 Tag Manager -->`;

const environmentInstallCode = `${commentOpen}<script src="${environmentInstallSrc}/${script}${opts}" async></script>${commentClose}`;
const environmentInstallCode = `${commentOpen}<script src="${props.installEndpoint}/${script}${opts}" async></script>${commentClose}`;

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ import { FC } from 'react';
import { Box, DialogContent, DialogContentText } from '@mui/material';
import { InfoButton, InfoProps } from '../molecules/InfoButton';
import InfoDialogTitle from '../molecules/InfoDialogTitle';
import EnvironmentInstallInstructions from './EnvironmentInstallInstructions';
import { Mode } from '../../gql/generated/globalTypes';
import EnvironmentInstallInstructions, {
InstallInstructionsProps,
} from './EnvironmentInstallInstructions';

export type InstallInstructionsDialogProps = {
export type InstallInstructionsDialogProps = InstallInstructionsProps & {
handleDialogClose: (checkChanges: boolean) => void;
installDomain: string;
title: string;
formInfoProps?: InfoProps;
cname: string;
environmentName: string;
environmentId: string;
mode: Mode;
tags: { name: string; code: string; type: string }[];
};

const EnvironmentInstallInstructionsDialog: FC<InstallInstructionsDialogProps> = (
props: InstallInstructionsDialogProps,
) => {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/organisms/Forms/ConditionRuleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getDataMapsIcon } from '../../../utils/TypeIconsUtils';
import { platformDataMapsToSubAndDeeper } from '../../../utils/PlatformDataMapsUtils';
import { buildConditionName } from '../../../dialogPages/tagManager/app/trigger/ConditionRuleUpdate';

const platformDataMapsToSelectValues = (
export const platformDataMapsToSelectValues = (
platformDataMaps: PlatformDataMap[],
): SelectValueWithSub[] => {
return platformDataMapsToSubAndDeeper(platformDataMaps).map((subAndDeeper) => {
Expand Down
47 changes: 44 additions & 3 deletions ui/src/components/organisms/Forms/IngestEndpointForm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import { FC } from 'react';
import { FC, useEffect, useState } from 'react';
import ControlledTextInput from '../../atoms/ControlledInputs/ControlledTextInput';
import DrawerFormLayout from '../../molecules/DrawerFormLayout';
import { IngestEndpointFormProps } from '../../../dialogPages/dataManager/IngestEndpointCreate';
import StorageProviderSelector from '../../molecules/StorageProviderSelector';
import CheckBoxInput from '../../atoms/InputTypes/CheckBoxInput';
import { Mode } from '../../../gql/generated/globalTypes';
import { IngestSchemaWizard, Mode } from '../../../gql/generated/globalTypes';
import { useConfigState } from '../../../context/AppContext';
import { Box } from '@mui/material';
import { Box, Checkbox, FormControlLabel } from '@mui/material';
import ControlledSelect from '../../atoms/ControlledInputs/ControlledSelect';
import { snakeToTitleCase } from '../../../utils/TextUtils';

const IngestEndpointForm: FC<IngestEndpointFormProps> = (props: IngestEndpointFormProps) => {
const { mode } = useConfigState();

const [useWizard, setUseWizard] = useState(false);

const { values, handleChange } = props;

useEffect(() => {
if (values.wizard !== '' && !useWizard) {
handleChange('wizard', '');
}
}, [values, handleChange, useWizard]);

return (
<DrawerFormLayout {...props}>
<ControlledTextInput
Expand All @@ -21,6 +33,35 @@ const IngestEndpointForm: FC<IngestEndpointFormProps> = (props: IngestEndpointFo
required
autoFocus
/>
{props.isCreate && (
<FormControlLabel
sx={{ marginBottom: (theme) => theme.spacing(3) }}
control={
<Checkbox
name="useWizard"
checked={useWizard}
onChange={(event) => {
setUseWizard(event.target.checked);
}}
color="primary"
/>
}
label="Use Wizard"
/>
)}
{useWizard && (
<ControlledSelect
className="DrawerFormField"
label="Wizard"
name="wizard"
values={Object.values(IngestSchemaWizard).map((_) => ({
key: _,
text: snakeToTitleCase(_),
}))}
formProps={props}
required
/>
)}
{mode !== Mode.COMMERCIAL && (
<>
<CheckBoxInput
Expand Down
31 changes: 16 additions & 15 deletions ui/src/dialogPages/dataManager/IngestEndpointCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import IngestEndpointForm from '../../components/organisms/Forms/IngestEndpointF
import { FormProps, FormValidationResult } from '../../hooks/form/useFormValidation';
import CreateIngestEndpointQuery from '../../gql/mutations/CreateIngestEndpointQuery';
import { ApolloError, useMutation } from '@apollo/client';
import { CreateIngestEndpointResult } from '../../gql/generated/CreateIngestEndpointResult';
import {
CreateIngestEndpointResult,
CreateIngestEndpointResultVariables,
} from '../../gql/generated/CreateIngestEndpointResult';
import { DialogPageProps } from '../../types/DialogTypes';
import { buildStandardFormInfo } from '../../utils/InfoLabelsUtils';
import {
Expand Down Expand Up @@ -67,28 +70,26 @@ const IngestEndpointCreate: FC<DialogPageProps> = (props: DialogPageProps) => {
buildInitialState: () => ({
...initialStorageProviderFields,
name: '',
wizard: '',
analyticsEnabled: false,
storageProvider: StorageProvider.MONGODB,
}),
saveQuery: useMutation<CreateIngestEndpointResult>(CreateIngestEndpointQuery),
mapSaveData: (formValues: IngestEndpointValues) => {
if (mode === Mode.COMMERCIAL) {
return {
ingestEndpointCreateInput: {
data_manager_account_id: dataManagerId,
name: formValues.name,
analytics_enabled: true,
},
};
}

mapSaveData: (formValues: IngestEndpointValues): CreateIngestEndpointResultVariables => {
return {
ingestEndpointCreateInput: {
data_manager_account_id: dataManagerId,
ingest_schema_wizard: formValues.wizard === '' ? undefined : formValues.wizard,
name: formValues.name,
analytics_enabled: formValues.analyticsEnabled,
storage_provider: formValues.storageProvider as StorageProvider,
...buildStorageProviderSaveProperties(formValues, true),
...(mode === Mode.COMMERCIAL
? {
analytics_enabled: true,
}
: {
analytics_enabled: formValues.analyticsEnabled,
storage_provider: formValues.storageProvider as StorageProvider,
...buildStorageProviderSaveProperties(formValues, true),
}),
},
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const IngestEndpointEnvironmentsInstallInstructions: FC<DialogPageProps> = (
>
<IngestEndpointInstallInstructions
installDomain={data.getIngestEndpointEnvironment.install_domain}
installEndpoint={data.getIngestEndpointEnvironment.install_endpoint}
cname={data.getIngestEndpointEnvironment.cname}
mode={mode}
environmentId={data.getIngestEndpointEnvironment.id}
Expand Down
Loading

0 comments on commit 2e62424

Please sign in to comment.