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

chore: type updates for rbac #26647

Merged
merged 6 commits into from
Dec 5, 2024
Merged
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
1 change: 1 addition & 0 deletions frontend/src/lib/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const MOCK_DEFAULT_TEAM: TeamType = {
autocapture_web_vitals_opt_in: false,
autocapture_exceptions_errors_to_ignore: [],
effective_membership_level: OrganizationMembershipLevel.Admin,
user_access_level: 'admin',
access_control: true,
has_group_types: true,
primary_dashboard: 1,
Expand Down
25 changes: 21 additions & 4 deletions frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,10 @@ class ApiRequest {
return await api.update(this.assembleFullUrl(), options?.data, options)
}

public async put(options?: ApiMethodOptions & { data: any }): Promise<any> {
return await api.put(this.assembleFullUrl(), options?.data, options)
}

public async create(options?: ApiMethodOptions & { data: any }): Promise<any> {
return await api.create(this.assembleFullUrl(), options?.data, options)
}
Expand Down Expand Up @@ -2554,14 +2558,19 @@ const api = {
})
},

async update(url: string, data: any, options?: ApiMethodOptions): Promise<any> {
async _update<T = any, P = any>(
method: 'PATCH' | 'PUT',
url: string,
data: P,
options?: ApiMethodOptions
): Promise<T> {
url = prepareUrl(url)
ensureProjectIdNotInvalid(url)
const isFormData = data instanceof FormData

const response = await handleFetch(url, 'PATCH', async () => {
const response = await handleFetch(url, method, async () => {
return await fetch(url, {
method: 'PATCH',
method: method,
headers: {
...objectClean(options?.headers ?? {}),
...(isFormData ? {} : { 'Content-Type': 'application/json' }),
Expand All @@ -2576,7 +2585,15 @@ const api = {
return await getJSONOrNull(response)
},

async create(url: string, data?: any, options?: ApiMethodOptions): Promise<any> {
async update<T = any, P = any>(url: string, data: P, options?: ApiMethodOptions): Promise<T> {
return api._update('PATCH', url, data, options)
},

async put<T = any, P = any>(url: string, data: P, options?: ApiMethodOptions): Promise<T> {
return api._update('PUT', url, data, options)
},

async create<T = any, P = any>(url: string, data?: P, options?: ApiMethodOptions): Promise<T> {
const res = await api.createResponse(url, data, options)
return await getJSONOrNull(res)
},
Expand Down
29 changes: 16 additions & 13 deletions frontend/src/models/dashboardsModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ export const dashboardsModel = kea<dashboardsModelType>([

const beforeChange = { ...values.rawDashboards[id] }

const response = (await api.update(
const response = await api.update<DashboardType>(
`api/environments/${teamLogic.values.currentTeamId}/dashboards/${id}`,
payload
)) as DashboardType
)
const updatedAttribute = Object.keys(payload)[0]
if (updatedAttribute === 'name' || updatedAttribute === 'description' || updatedAttribute === 'tags') {
eventUsageLogic.actions.reportDashboardFrontEndUpdate(
Expand All @@ -134,10 +134,10 @@ export const dashboardsModel = kea<dashboardsModelType>([
button: {
label: 'Undo',
action: async () => {
const reverted = (await api.update(
const reverted = await api.update<DashboardType>(
`api/environments/${teamLogic.values.currentTeamId}/dashboards/${id}`,
beforeChange
)) as DashboardType
)
actions.updateDashboardSuccess(getQueryBasedDashboard(reverted))
lemonToast.success('Dashboard change reverted')
},
Expand All @@ -160,31 +160,34 @@ export const dashboardsModel = kea<dashboardsModelType>([
})
) as DashboardType<QueryBasedInsightModel>,
pinDashboard: async ({ id, source }) => {
const response = (await api.update(
const response = await api.update(
`api/environments/${teamLogic.values.currentTeamId}/dashboards/${id}`,
{
pinned: true,
}
)) as DashboardType
)
eventUsageLogic.actions.reportDashboardPinToggled(true, source)
return getQueryBasedDashboard(response)!
},
unpinDashboard: async ({ id, source }) => {
const response = (await api.update(
const response = await api.update<DashboardType>(
`api/environments/${teamLogic.values.currentTeamId}/dashboards/${id}`,
{
pinned: false,
}
)) as DashboardType
)
eventUsageLogic.actions.reportDashboardPinToggled(false, source)
return getQueryBasedDashboard(response)!
},
duplicateDashboard: async ({ id, name, show, duplicateTiles }) => {
const result = (await api.create(`api/environments/${teamLogic.values.currentTeamId}/dashboards/`, {
use_dashboard: id,
name: `${name} (Copy)`,
duplicate_tiles: duplicateTiles,
})) as DashboardType
const result = await api.create<DashboardType>(
`api/environments/${teamLogic.values.currentTeamId}/dashboards/`,
{
use_dashboard: id,
name: `${name} (Copy)`,
duplicate_tiles: duplicateTiles,
}
)
if (show) {
router.actions.push(urls.dashboard(result.id))
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/authentication/login2FALogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const login2FALogic = kea<login2FALogicType>([
submit: async ({ token }, breakpoint) => {
breakpoint()
try {
return await api.create('api/login/token', { token })
return await api.create<any>('api/login/token', { token })
} catch (e) {
const { code, detail } = e as Record<string, any>
actions.setGeneralError(code, detail)
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/authentication/loginLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const loginLogic = kea<loginLogicType>([
}

breakpoint()
const response = await api.create('api/login/precheck', { email })
const response = await api.create<any>('api/login/precheck', { email })
return { status: 'completed', ...response }
},
},
Expand All @@ -102,7 +102,7 @@ export const loginLogic = kea<loginLogicType>([
submit: async ({ email, password }, breakpoint) => {
breakpoint()
try {
return await api.create('api/login', { email, password })
return await api.create<any>('api/login', { email, password })
} catch (e) {
const { code } = e as Record<string, any>
let { detail } = e as Record<string, any>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/scenes/authentication/setup2FALogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const setup2FALogic = kea<setup2FALogicType>([
null as { backup_codes: string[] } | null,
{
generateBackupCodes: async () => {
return await api.create('api/users/@me/two_factor_backup_codes/')
return await api.create<any>('api/users/@me/two_factor_backup_codes/')
},
},
],
Expand All @@ -95,7 +95,7 @@ export const setup2FALogic = kea<setup2FALogicType>([
{
disable2FA: async () => {
try {
await api.create('api/users/@me/two_factor_disable/')
await api.create<any>('api/users/@me/two_factor_disable/')
return true
} catch (e) {
const { code, detail } = e as Record<string, any>
Expand All @@ -114,7 +114,7 @@ export const setup2FALogic = kea<setup2FALogicType>([
submit: async ({ token }, breakpoint) => {
breakpoint()
try {
return await api.create('api/users/@me/validate_2fa/', { token })
return await api.create<any>('api/users/@me/validate_2fa/', { token })
} catch (e) {
const { code, detail } = e as Record<string, any>
actions.setGeneralError(code, detail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const REGULAR_FEATURE_FLAG: FeatureFlagType = {
rollback_conditions: [],
performed_rollback: false,
can_edit: true,
user_access_level: 'editor',
tags: [],
surveys: [],
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/scenes/feature-flags/activityDescriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ const featureFlagActionsMapping: Record<
analytics_dashboards: () => null,
has_enriched_analytics: () => null,
surveys: () => null,
user_access_level: () => null,
}

export function flagActivityDescriber(logItem: ActivityLogItem, asNotification?: boolean): HumanizedChange {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/scenes/feature-flags/featureFlagLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const NEW_FLAG: FeatureFlagType = {
surveys: null,
performed_rollback: false,
can_edit: true,
user_access_level: 'editor',
tags: [],
}
const NEW_VARIANT = {
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/scenes/instance/SystemStatus/staffUsersLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ export const staffUsersLogic = kea<staffUsersLogicType>([
actions.setStaffUsersToBeAdded([])
const newStaffUsers = await Promise.all(
staffUsersToBeAdded.map(
async (userUuid) =>
(await api.update(`api/users/${userUuid}`, { is_staff: true })) as UserType
async (userUuid) => await api.update<UserType>(`api/users/${userUuid}`, { is_staff: true })
)
)
const updatedAllUsers: UserType[] = [
Expand All @@ -45,7 +44,7 @@ export const staffUsersLogic = kea<staffUsersLogicType>([
return updatedAllUsers
},
deleteStaffUser: async ({ userUuid }) => {
await api.update(`api/users/${userUuid}`, { is_staff: false })
await api.update<UserType>(`api/users/${userUuid}`, { is_staff: false })
if (values.user?.uuid === userUuid) {
actions.loadUser() // Loads the main user object to properly reflect staff user changes
router.actions.push(urls.projectHomepage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const notebookTestTemplate = (
last_modified_at: '2023-06-02T00:00:00Z',
created_by: MOCK_DEFAULT_BASIC_USER,
last_modified_by: MOCK_DEFAULT_BASIC_USER,
user_access_level: 'editor' as const,
version: 1,
content: {
type: 'doc',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -933,10 +933,12 @@ describe('migrate()', () => {
it.each(contentToExpected)('migrates %s', (_name, prevContent, nextContent) => {
const prevNotebook: NotebookType = {
...mockNotebook,
user_access_level: 'editor' as const,
content: { type: 'doc', content: prevContent },
}
const nextNotebook: NotebookType = {
...mockNotebook,
user_access_level: 'editor' as const,
content: { type: 'doc', content: nextContent },
}

Expand Down
1 change: 1 addition & 0 deletions frontend/src/scenes/notebooks/Notebook/notebookLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const notebookLogic = kea<notebookLogicType>([
content: null,
text_content: null,
version: 0,
user_access_level: 'editor',
}
} else if (props.shortId.startsWith('template-')) {
response =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const LOCAL_NOTEBOOK_TEMPLATES: NotebookType[] = [
last_modified_at: '2023-06-02T00:00:00Z',
created_by: TEMPLATE_USERS.posthog,
last_modified_by: TEMPLATE_USERS.posthog,
user_access_level: 'viewer' as const,
version: 1,
content: {
type: 'doc',
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/projectLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ export const projectLogic = kea<projectLogicType>([
throw new Error('Current project has not been loaded yet, so it cannot be updated!')
}

const patchedProject = (await api.update(
const patchedProject = await api.update<ProjectType>(
`api/projects/${values.currentProject.id}`,
payload
)) as ProjectType
)
breakpoint()

// We need to reload current org (which lists its projects) in organizationLogic AND in userLogic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ exports[`verifiedDomainsLogic values has proper defaults 1`] = `
"test_account_filters_default_checked": false,
"timezone": "UTC",
"updated_at": "2022-03-17T16:09:21.566253Z",
"user_access_level": "admin",
"uuid": "TEAM_UUID",
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,12 @@ export const verifiedDomainsLogic = kea<verifiedDomainsLogicType>([
(await api.get(`api/organizations/${values.currentOrganization?.id}/domains`))
.results as OrganizationDomainType[],
addVerifiedDomain: async (domain: string) => {
const response = await api.create(`api/organizations/${values.currentOrganization?.id}/domains`, {
domain,
})
const response = await api.create<OrganizationDomainType>(
`api/organizations/${values.currentOrganization?.id}/domains`,
{
domain,
}
)
return [response, ...values.verifiedDomains]
},
deleteVerifiedDomain: async (id: string) => {
Expand All @@ -93,18 +96,18 @@ export const verifiedDomainsLogic = kea<verifiedDomainsLogicType>([
false,
{
updateDomain: async (payload: OrganizationDomainUpdatePayload) => {
const response = await api.update(
const response = await api.update<OrganizationDomainType>(
`api/organizations/${values.currentOrganization?.id}/domains/${payload.id}`,
{ ...payload, id: undefined }
)
lemonToast.success('Domain updated successfully! Changes will take immediately.')
actions.replaceDomain(response as OrganizationDomainType)
actions.replaceDomain(response)
return false
},
verifyDomain: async () => {
const response = (await api.create(
const response = await api.create<OrganizationDomainType>(
`api/organizations/${values.currentOrganization?.id}/domains/${values.verifyModal}/verify`
)) as OrganizationDomainType
)
if (response.is_verified) {
lemonToast.success('Domain verified successfully.')
} else {
Expand Down Expand Up @@ -158,12 +161,12 @@ export const verifiedDomainsLogic = kea<verifiedDomainsLogicType>([
if (!id) {
return
}
const response = (await api.update(
const response = await api.update<OrganizationDomainType>(
`api/organizations/${values.currentOrganization?.id}/domains/${payload.id}`,
{
...updateParams,
}
)) as OrganizationDomainType
)
breakpoint()
actions.replaceDomain(response)
actions.setConfigureSAMLModalId(null)
Expand Down
15 changes: 11 additions & 4 deletions frontend/src/scenes/settings/organization/inviteLogic.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { actions, connect, events, kea, listeners, path, reducers, selectors } from 'kea'
import { loaders } from 'kea-loaders'
import { router, urlToAction } from 'kea-router'
import api from 'lib/api'
import api, { PaginatedResponse } from 'lib/api'
import { OrganizationMembershipLevel } from 'lib/constants'
import { lemonToast } from 'lib/lemon-ui/LemonToast/LemonToast'
import { organizationLogic } from 'scenes/organizationLogic'
Expand Down Expand Up @@ -49,15 +49,18 @@ export const inviteLogic = kea<inviteLogicType>([
{
inviteTeamMembers: async () => {
if (!values.canSubmit) {
return { invites: [] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing this didn't previously fail type validation 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a lot of weird type things with kea that seem to pass for now reason.

return []
}

const payload: Pick<OrganizationInviteType, 'target_email' | 'first_name' | 'level' | 'message'>[] =
values.invitesToSend.filter((invite) => invite.target_email)
if (values.message) {
payload.forEach((payload) => (payload.message = values.message))
}
return await api.create('api/organizations/@current/invites/bulk/', payload)
return await api.create<OrganizationInviteType[]>(
'api/organizations/@current/invites/bulk/',
payload
)
},
},
],
Expand All @@ -66,7 +69,11 @@ export const inviteLogic = kea<inviteLogicType>([
{
loadInvites: async () => {
return organizationLogic.values.currentOrganization
? (await api.get('api/organizations/@current/invites/')).results
? (
await api.get<PaginatedResponse<OrganizationInviteType>>(
'api/organizations/@current/invites/'
)
).results
: []
},
deleteInvite: async (invite: OrganizationInviteType) => {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/scenes/teamActivityDescriber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ const teamActionsMapping: Record<
id: () => null,
updated_at: () => null,
uuid: () => null,
user_access_level: () => null,
live_events_token: () => null,
product_intents: () => null,
}
Expand Down
Loading
Loading