/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import type { SqlExpression } from 'druid-query-toolkit'; import { SqlLiteral, SqlTable } from 'druid-query-toolkit'; import { useCallback, useEffect, useState } from 'react'; import { useStore } from 'zustand'; import { shallow } from 'zustand/shallow'; import type { SqlQueryPayload } from './host'; import { Host } from './host'; import type { HostStorePersistOptions, RegisteredVisualModule } from './host-store'; import type { ParameterDefinitions } from './parameter'; import type { ParametersToParams, VisualModule } from './visual-module'; interface UseHostOptions { sqlQuery: (payload: SqlQueryPayload) => Promise; table: SqlExpression; persist?: HostStorePersistOptions; visualModules: Record>; selectedModules: string[]; where?: string | SqlExpression; } export function useHost(options: UseHostOptions) { const { sqlQuery, table, persist, visualModules, selectedModules, where = SqlLiteral.TRUE, } = options; const [host] = useState(() => { const host = Host({ sqlQuery, persist, where, table, }); return host; }); useEffect(() => { for (const [name, module] of Object.entries>(visualModules)) { host.registerVisualModule(name, module); } }, []); const callbacks = useHostStore({ host, selectedModules }); return { host, ...callbacks, }; } function useHostStore(options: { host: Host; selectedModules: string[] }) { const { host, selectedModules } = options; return useStore( host.store, useCallback( state => { const paramsPerModule: Record> = {}; const visualModules: Record = {}; selectedModules.forEach(m => { paramsPerModule[m] = state.getModuleParams(m); visualModules[m] = state.visualModules ? state.visualModules[m] : undefined; }); const onUpdateParams = (params: Record, selectedModule: string) => state.setModuleParams(selectedModule, params); return { where: state.where, having: state.having, params: paramsPerModule, onUpdateParams, visualModules, table: SqlTable.parse(state.table) as SqlTable, }; }, [selectedModules], ), shallow, ); }