Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: self hosted onboarding #5057

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions frontend/common/loadCrisp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default async function (crispWebsiteId: string) {
// @ts-ignore
if (window.$crisp) {
return
}
// @ts-ignore
window.$crisp = []
// @ts-ignore
window.CRISP_WEBSITE_ID = crispWebsiteId
await new Promise((resolve, reject) => {
const d = document
const s = d.createElement('script')
s.src = 'https://client.crisp.chat/l.js'
s.async = true
s.onload = resolve
s.onerror = reject
d.getElementsByTagName('head')[0].appendChild(s)
})
}
82 changes: 82 additions & 0 deletions frontend/common/services/useBuildVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Req } from 'common/types/requests'
import { service } from 'common/service'

import { Version } from 'common/types/responses'
import Project from 'common/project'
import { StoreStateType } from 'common/store'

export const buildVersionService = service
.enhanceEndpoints({ addTagTypes: ['BuildVersion'] })
.injectEndpoints({
endpoints: (builder) => ({
getBuildVersion: builder.query<Version, Req['getBuildVersion']>({
providesTags: () => [{ id: 'BuildVersion', type: 'BuildVersion' }],
queryFn: async (args, _, _2, baseQuery) => {
// Fire both requests concurrently
const [frontendRes, backendRes] = await Promise.all([
baseQuery('/version').then(
(res: { data?: Version['frontend'] }) => {
if (res.data) {
return res.data
}
return {}
},
),
baseQuery(`${Project.api.replace('api/v1/', '')}version`).then(
(res: { data: Version['backend'] }) => res.data,
),
])

if (backendRes.error) {
return { error: backendRes.error }
}

const frontend = (frontendRes.data || {}) as Version['frontend']
const backend =
(backendRes.data as Version['backend']) ||
({} as Version['backend'])

const tag = backend?.image_tag || 'Unknown'
const backend_sha = backend?.ci_commit_sha || 'Unknown'
const frontend_sha = frontend?.ci_commit_sha || 'Unknown'

const result: Version = {
backend,
backend_sha,
frontend,
frontend_sha,
tag,
}

return { data: result }
},
}),
// END OF ENDPOINTS
}),
})

export async function getBuildVersion(
store: any,
data: Req['getBuildVersion'],
options?: Parameters<
typeof buildVersionService.endpoints.getBuildVersion.initiate
>[1],
) {
return store.dispatch(
buildVersionService.endpoints.getBuildVersion.initiate(data, options),
)
}
// END OF FUNCTION_EXPORTS

export const selectBuildVersion = (state: StoreStateType) => state.buildVersion

export const {
useGetBuildVersionQuery,
// END OF EXPORTS
} = buildVersionService

/* Usage examples:
const { data, isLoading } = useGetBuildVersionQuery({ id: 2 }, {}) //get hook
const [createBuildVersion, { isLoading, data, isSuccess }] = useCreateBuildVersionMutation() //create hook
buildVersionService.endpoints.getBuildVersion.select({id: 2})(store.getState()) //access data from any function
*/
46 changes: 46 additions & 0 deletions frontend/common/services/useOnboarding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Res } from 'common/types/responses'
import { Req } from 'common/types/requests'
import { service } from 'common/service'

export const onboardingService = service
.enhanceEndpoints({ addTagTypes: ['Onboarding'] })
.injectEndpoints({
endpoints: (builder) => ({
createOnboarding: builder.mutation<
Res['onboarding'],
Req['createOnboarding']
>({
invalidatesTags: [{ id: 'LIST', type: 'Onboarding' }],
query: (query: Req['createOnboarding']) => ({
body: query,
method: 'POST',
url: `onboarding`,
}),
}),
// END OF ENDPOINTS
}),
})

export async function createOnboarding(
store: any,
data: Req['createOnboarding'],
options?: Parameters<
typeof onboardingService.endpoints.createOnboarding.initiate
>[1],
) {
return store.dispatch(
onboardingService.endpoints.createOnboarding.initiate(data, options),
)
}
// END OF FUNCTION_EXPORTS

export const {
useCreateOnboardingMutation,
// END OF EXPORTS
} = onboardingService

/* Usage examples:
const { data, isLoading } = useGetOnboardingQuery({ id: 2 }, {}) //get hook
const [createOnboarding, { isLoading, data, isSuccess }] = useCreateOnboardingMutation() //create hook
onboardingService.endpoints.getOnboarding.select({id: 2})(store.getState()) //access data from any function
*/
21 changes: 21 additions & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ export type CreateVersionFeatureState = {
sha: string
featureState: FeatureState
}

export type LoginRequest = {
email: string
password: string
}
export type RegisterRequest = {
email: string
first_name: string
last_name: string
marketing_consent_given: boolean
password: string
}
export type Req = {
getSegments: PagedRequest<{
q?: string
Expand Down Expand Up @@ -597,5 +609,14 @@ export type Req = {
identity: string
projectId: string
}>
createOnboarding: {
first_name: string
last_name: string
email: string
password: string
contact_consent_given: boolean
organisation_name: string
}
getBuildVersion: {}
// END OF TYPES
}
21 changes: 21 additions & 0 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,23 @@ export type HealthProvider = {
webhook_url: number
}

export type Version = {
tag: string
backend_sha: string
frontend_sha: string
frontend: {
ci_commit_sha?: string
image_tag?: string
}
backend: {
ci_commit_sha: string
image_tag: string
has_email_provider: boolean
is_enterprise: boolean
is_saas: boolean
}
}

export type Webhook = {
id: number
url: string
Expand All @@ -668,6 +685,10 @@ export type Webhook = {
updated_at: string
}

export type AccountModel = User & {
organisations: Organisation[]
}

export type IdentityTrait = {
id: number | string
trait_key: string
Expand Down
7 changes: 7 additions & 0 deletions frontend/common/utils/isFreeEmailDomain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import freeEmailDomains from 'free-email-domains'

export default function (value: string | null | undefined) {
if (!value) return false
const domain = value?.split('@')?.[1]
return freeEmailDomains.includes(domain)
}
Loading
Loading