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(bi): Add the ability to update variables #25659

Merged
merged 9 commits into from
Oct 18, 2024
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,9 @@ class ApiRequest {
public insightVariables(teamId?: TeamType['id']): ApiRequest {
return this.projectsDetail(teamId).addPathComponent('insight_variables')
}
public insightVariable(variableId: string, teamId?: TeamType['id']): ApiRequest {
return this.insightVariables(teamId).addPathComponent(variableId)
}

// ActivityLog
public activity_log(teamId?: TeamType['id']): ApiRequest {
Expand Down Expand Up @@ -2304,9 +2307,12 @@ const api = {
async list(options?: ApiMethodOptions | undefined): Promise<PaginatedResponse<Variable>> {
return await new ApiRequest().insightVariables().get(options)
},
async create(data: Partial<any>): Promise<Variable> {
async create(data: Partial<Variable>): Promise<Variable> {
return await new ApiRequest().insightVariables().create({ data })
},
async update(variableId: string, data: Partial<Variable>): Promise<Variable> {
return await new ApiRequest().insightVariable(variableId).update({ data })
},
},

subscriptions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'

import { dataVisualizationLogic } from '../../dataVisualizationLogic'
import { addVariableLogic } from './addVariableLogic'
import { NewVariableModal } from './NewVariableModal'
import { variableModalLogic } from './variableModalLogic'
import { variablesLogic } from './variablesLogic'

export const AddVariableButton = (): JSX.Element => {
const { showEditingUI } = useValues(dataVisualizationLogic)
const { featureFlags } = useValues(featureFlagLogic)
const { openModal } = useActions(addVariableLogic)
const { openNewVariableModal } = useActions(variableModalLogic)

const { variables, variablesLoading } = useValues(variablesLogic)
const { addVariable } = useActions(variablesLogic)
Expand All @@ -30,19 +30,19 @@ export const AddVariableButton = (): JSX.Element => {
items: [
{
label: 'String',
onClick: () => openModal('String'),
onClick: () => openNewVariableModal('String'),
},
{
label: 'Number',
onClick: () => openModal('Number'),
onClick: () => openNewVariableModal('Number'),
},
{
label: 'Boolean',
onClick: () => openModal('Boolean'),
onClick: () => openNewVariableModal('Boolean'),
},
{
label: 'List',
onClick: () => openModal('List'),
onClick: () => openNewVariableModal('List'),
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useActions, useValues } from 'kea'
import { LemonField } from 'lib/lemon-ui/LemonField'

import { Variable } from '../../types'
import { addVariableLogic } from './addVariableLogic'
import { variableModalLogic } from './variableModalLogic'

const renderVariableSpecificFields = (
variable: Variable,
Expand Down Expand Up @@ -95,12 +95,14 @@ const renderVariableSpecificFields = (
}

export const NewVariableModal = (): JSX.Element => {
const { closeModal, updateVariable, save } = useActions(addVariableLogic)
const { isModalOpen, variable } = useValues(addVariableLogic)
const { closeModal, updateVariable, save } = useActions(variableModalLogic)
const { isModalOpen, variable, modalType } = useValues(variableModalLogic)

const title = modalType === 'new' ? `New ${variable.type} variable` : `Editing ${variable.name}`

return (
<LemonModal
title={`New ${variable.type} variable`}
title={title}
isOpen={isModalOpen}
onClose={closeModal}
maxWidth="30rem"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { dataNodeLogic } from '~/queries/nodes/DataNode/dataNodeLogic'
import { dataVisualizationLogic } from '../../dataVisualizationLogic'
import { Variable } from '../../types'
import { NewVariableModal } from './NewVariableModal'
import { variableModalLogic } from './variableModalLogic'
import { variablesLogic } from './variablesLogic'

export const VariablesForDashboard = (): JSX.Element => {
Expand Down Expand Up @@ -49,6 +50,7 @@ export const VariablesForInsight = (): JSX.Element => {
const { updateVariableValue, removeVariable } = useActions(variablesLogic)
const { showEditingUI } = useValues(dataVisualizationLogic)
const { variableOverridesAreSet } = useValues(dataNodeLogic)
const { openExistingVariableModal } = useActions(variableModalLogic)

if (!featureFlags[FEATURE_FLAGS.INSIGHT_VARIABLES] || !variablesForInsight.length || !showVariablesBar) {
return <></>
Expand All @@ -65,6 +67,7 @@ export const VariablesForInsight = (): JSX.Element => {
onChange={updateVariableValue}
onRemove={removeVariable}
variableOverridesAreSet={variableOverridesAreSet}
variableSettingsOnClick={() => openExistingVariableModal(n)}
/>
))}
</div>
Expand All @@ -79,6 +82,7 @@ interface VariableInputProps {
closePopover: () => void
onChange: (variableId: string, value: any) => void
onRemove?: (variableId: string) => void
variableSettingsOnClick?: () => void
}

const VariableInput = ({
Expand All @@ -87,6 +91,7 @@ const VariableInput = ({
closePopover,
onChange,
onRemove,
variableSettingsOnClick,
}: VariableInputProps): JSX.Element => {
const [localInputValue, setLocalInputValue] = useState(() => {
const val = variable.value ?? variable.default_value
Expand Down Expand Up @@ -191,7 +196,7 @@ const VariableInput = ({
}
}
}}
className="text-xs flex flex-1 items-center"
className="text-xs flex flex-1 items-center mr-2"
>
{variableAsHogQL}
</code>
Expand All @@ -209,7 +214,14 @@ const VariableInput = ({
tooltip="Remove variable from insight"
/>
)}
<LemonButton icon={<IconGear />} size="xsmall" tooltip="Open variable settings" />
{variableSettingsOnClick && (
<LemonButton
onClick={variableSettingsOnClick}
icon={<IconGear />}
size="xsmall"
tooltip="Open variable settings"
/>
)}
</div>
</>
)}
Expand All @@ -223,6 +235,7 @@ interface VariableComponentProps {
onChange: (variableId: string, value: any) => void
variableOverridesAreSet: boolean
onRemove?: (variableId: string) => void
variableSettingsOnClick?: () => void
}

const VariableComponent = ({
Expand All @@ -231,6 +244,7 @@ const VariableComponent = ({
onChange,
variableOverridesAreSet,
onRemove,
variableSettingsOnClick,
}: VariableComponentProps): JSX.Element => {
const [isPopoverOpen, setPopoverOpen] = useState(false)

Expand All @@ -244,6 +258,12 @@ const VariableComponent = ({
onChange={onChange}
closePopover={() => setPopoverOpen(false)}
onRemove={onRemove}
variableSettingsOnClick={() => {
if (variableSettingsOnClick) {
setPopoverOpen(false)
variableSettingsOnClick()
}
}}
/>
}
visible={isPopoverOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { actions, connect, kea, key, listeners, path, props, reducers } from 'ke
import api, { ApiError } from 'lib/api'

import { BooleanVariable, ListVariable, NumberVariable, StringVariable, Variable, VariableType } from '../../types'
import type { addVariableLogicType } from './addVariableLogicType'
import { variableDataLogic } from './variableDataLogic'
import type { variableModalLogicType } from './variableModalLogicType'
import { variablesLogic } from './variablesLogic'

const DEFAULT_VARIABLE: StringVariable = {
Expand All @@ -19,37 +19,48 @@ export interface AddVariableLogicProps {
key: string
}

export const addVariableLogic = kea<addVariableLogicType>([
export const variableModalLogic = kea<variableModalLogicType>([
path(['queries', 'nodes', 'DataVisualization', 'Components', 'Variables', 'variableLogic']),
props({ key: '' } as AddVariableLogicProps),
key((props) => props.key),
connect({
actions: [variableDataLogic, ['getVariables'], variablesLogic, ['addVariable']],
}),
actions({
openModal: (variableType: VariableType) => ({ variableType }),
openNewVariableModal: (variableType: VariableType) => ({ variableType }),
openExistingVariableModal: (variable: Variable) => ({ variable }),
closeModal: true,
updateVariable: (variable: Variable) => ({ variable }),
save: true,
}),
reducers({
modalType: [
'new' as 'new' | 'existing',
{
openNewVariableModal: () => 'new',
openExistingVariableModal: () => 'existing',
},
],
variableType: [
'string' as VariableType,
{
openModal: (_, { variableType }) => variableType,
openNewVariableModal: (_, { variableType }) => variableType,
openExistingVariableModal: (_, { variable }) => variable.type,
},
],
isModalOpen: [
false as boolean,
{
openModal: () => true,
openNewVariableModal: () => true,
openExistingVariableModal: () => true,
closeModal: () => false,
},
],
variable: [
DEFAULT_VARIABLE as Variable,
{
openModal: (_, { variableType }) => {
openExistingVariableModal: (_, { variable }) => ({ ...variable }),
openNewVariableModal: (_, { variableType }) => {
if (variableType === 'String') {
return {
id: '',
Expand Down Expand Up @@ -101,10 +112,14 @@ export const addVariableLogic = kea<addVariableLogicType>([
listeners(({ values, actions }) => ({
save: async () => {
try {
const variable = await api.insightVariables.create(values.variable)
if (values.modalType === 'new') {
const variable = await api.insightVariables.create(values.variable)
actions.addVariable({ variableId: variable.id, code_name: variable.code_name })
} else {
await api.insightVariables.update(values.variable.id, values.variable)
}

actions.getVariables()
actions.addVariable({ variableId: variable.id, code_name: variable.code_name })
actions.closeModal()
} catch (e: any) {
const error = e as ApiError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { SideBar } from './Components/SideBar'
import { Table } from './Components/Table'
import { TableDisplay } from './Components/TableDisplay'
import { AddVariableButton } from './Components/Variables/AddVariableButton'
import { addVariableLogic } from './Components/Variables/addVariableLogic'
import { variableModalLogic } from './Components/Variables/variableModalLogic'
import { VariablesForInsight } from './Components/Variables/Variables'
import { variablesLogic } from './Components/Variables/variablesLogic'
import { dataVisualizationLogic, DataVisualizationLogicProps } from './dataVisualizationLogic'
Expand Down Expand Up @@ -104,7 +104,7 @@ export function DataTableVisualization({
logic={variablesLogic}
props={{ key: dataVisualizationLogicProps.key, readOnly: readOnly ?? false }}
>
<BindLogic logic={addVariableLogic} props={{ key: dataVisualizationLogicProps.key }}>
<BindLogic logic={variableModalLogic} props={{ key: dataVisualizationLogicProps.key }}>
<InternalDataTableVisualization
uniqueKey={key}
query={query}
Expand Down
Loading