Skip to content

Commit

Permalink
Develop (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
walbuc authored Sep 3, 2024
2 parents a80fb4d + 1fbe4fa commit b1a3b34
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 84 deletions.
2 changes: 1 addition & 1 deletion src/components/DrawerMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
import type {PlainLevel} from "@datawheel/olap-client";
import {getCaption} from "../utils/string";
import {abbreviateFullName} from "../utils/format";
import {levelRefToArray, joinName, stringifyName} from "../utils/transform";
import {stringifyName} from "../utils/transform";
import {Comparison} from "@datawheel/olap-client";
import {getFiltersConditions} from "./TableView";
import {BarsSVG, StackSVG} from "./icons";
Expand Down
3 changes: 2 additions & 1 deletion src/components/ExplorerResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function SuccessResult(props: {

const queryItem = useSelector(selectCurrentQueryItem);
const isPreviewMode = useSelector(selectIsPreviewMode);
const {table, isError, isLoading, data} = useTable({cube, result});
const {table, isError, isLoading, data, columns} = useTable({cube, result});

const fullscreen = useFullscreen();

Expand Down Expand Up @@ -252,6 +252,7 @@ function SuccessResult(props: {
isError={isError}
isLoading={isLoading}
data={data}
columns={columns}
/>
</Box>
</Flex>
Expand Down
30 changes: 15 additions & 15 deletions src/components/TableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
Table,
Center,
MultiSelect,
ScrollArea
ScrollArea,
LoadingOverlay
} from "@mantine/core";
import {IconAlertCircle, IconTrash} from "@tabler/icons-react";
import {
Expand All @@ -26,18 +27,11 @@ import {
import React, {useEffect, useLayoutEffect, useMemo, useState} from "react";
import {useFormatter} from "../hooks/formatter";
import {useTranslation} from "../hooks/translation";
import {
AnyResultColumn,
buildCut,
buildDrilldown,
buildFilter,
buildMeasure
} from "../utils/structs";
import {AnyResultColumn, buildFilter, buildMeasure} from "../utils/structs";
import {BarsSVG, StackSVG} from "./icons";
import {
selectCutItems,
selectDrilldownItems,
selectDrilldownMap,
selectFilterItems,
selectFilterMap,
selectMeasureItems,
Expand Down Expand Up @@ -75,9 +69,8 @@ import {
NumberInputComponent
} from "./DrawerMenu";
import debounce from "lodash.debounce";
import {selectOlapDimensionItems, selectOlapMeasureItems} from "../state/selectors";
import {selectOlapMeasureItems} from "../state/selectors";
import {filterMap} from "../utils/array";
import {stringifyName} from "../utils/transform";

type EntityTypes = "measure" | "level" | "property";
type TData = Record<string, any> & Record<string, string | number>;
Expand Down Expand Up @@ -258,7 +251,7 @@ function useTableData({columns, filters, cuts, pagination}: useTableDataType) {
const handler = debounce(() => {
const term = [columnsStr, filterKey, cutKey, page];
setDebouncedTerm(term);
}, 700);
}, 800);
handler();
return () => handler.cancel();
}, [columnsStr, filterKey, cutKey, page, enabled]);
Expand Down Expand Up @@ -397,7 +390,10 @@ export function useTable({

const {isLoading, isFetching, isError, data, isPlaceholderData} = useTableData({
columns: finalUniqueKeys,
filters: filterItems.filter(isActiveItem),
filters: filterItems.filter(
f =>
isActiveItem(f) && isActiveItem(measures.find(m => m.name === f.measure) || {active: false})
),
cuts: itemsCuts.filter(isActiveCut),
pagination
});
Expand Down Expand Up @@ -465,6 +461,7 @@ export function useTable({
range,
isId
} = column;

const isNumeric = valueType === "number" && columnKey !== "Year";
const formatterKey = getFormatterKey(columnKey) || (isNumeric ? "Decimal" : "identity");
const formatter = getFormatter(formatterKey);
Expand Down Expand Up @@ -648,17 +645,19 @@ export function useTable({
...mantineTableProps
});

return {table, isError, isLoading, data: tableData};
return {table, isError, isLoading, data: tableData, columns};
}

type TableView = {
table: MRT_TableInstance<TData>;
getColumn(id: String): AnyResultColumn | undefined;
columns: AnyResultColumn[];
} & ViewProps;

export function TableView({table, result, isError, isLoading, data}: TableView) {
export function TableView({table, result, isError, isLoading = false, data, columns}: TableView) {
// This is not accurate because mantine adds fake rows when is loading.
const isData = Boolean(table.getRowModel().rows.length);

return (
<Box sx={{height: "100%"}}>
<Flex direction="column" justify="space-between" sx={{height: "100%", flex: "1 1 auto"}}>
Expand All @@ -671,6 +670,7 @@ export function TableView({table, result, isError, isLoading, data}: TableView)
overflow: "scroll"
}}
>
<LoadingOverlay visible={columns.length === 0 && isLoading} />
<Table
captionSide="top"
fontSize="md"
Expand Down
120 changes: 56 additions & 64 deletions src/state/queries.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { PayloadAction as Action, createSelector, createSlice } from "@reduxjs/toolkit";
import {PayloadAction as Action, createSelector, createSlice} from "@reduxjs/toolkit";
import ISO6391 from "iso-639-1";
import { sortByDate } from "../utils/array";
import { getKeys, getValues, hasOwnProperty } from "../utils/object";
import { CutItem, DrilldownItem, FilterItem, MeasureItem, QueryItem, QueryParams, QueryResult, buildQuery, buildQueryParams } from "../utils/structs";
import { isValidQueryVerbose } from "../utils/validation";
import { selectServerState } from "./server";
import type { ExplorerState } from "./store";
import {sortByDate} from "../utils/array";
import {getKeys, getValues, hasOwnProperty} from "../utils/object";
import {
CutItem,
DrilldownItem,
FilterItem,
MeasureItem,
QueryItem,
QueryParams,
QueryResult,
buildQuery,
buildQueryParams
} from "../utils/structs";
import {isValidQueryVerbose} from "../utils/validation";
import {selectServerState} from "./server";
import type {ExplorerState} from "./store";

export interface QueriesState {
current: string;
Expand All @@ -17,7 +27,7 @@ const name = "explorerQueries";
const initialState: QueriesState = {
current: "default",
itemMap: {
default: buildQuery({ key: "default" })
default: buildQuery({key: "default"})
}
};

Expand All @@ -33,7 +43,7 @@ export const queriesSlice = createSlice({
* If passed a payload, replaces the query map from the application state
* with its contents, and selects a new current query in the UI.
*/
resetQueries(state, { payload = {} }: Action<Record<string, any>>) {
resetQueries(state, {payload = {}}: Action<Record<string, any>>) {
if (!hasOwnProperty(payload, state.current)) {
state.current = Object.keys(payload)[0];
}
Expand Down Expand Up @@ -67,7 +77,7 @@ export const queriesSlice = createSlice({
* Updates the contents of a query.
* The payload replaces the query in the state, instead of extending it.
*/
updateQuery(state, { payload }: Action<QueryItem>) {
updateQuery(state, {payload}: Action<QueryItem>) {
state.itemMap[payload.key] = payload;
},

Expand All @@ -93,11 +103,10 @@ export const queriesSlice = createSlice({
removeDrilldown(state, action: Action<string>) {
const query = taintCurrentQuery(state);
delete query.params.drilldowns[action.payload];

},
/**
* Remove a single DrilldownItem from the current QueryItem.
*/
* Remove a single DrilldownItem from the current QueryItem.
*/
removeMeasure(state, action: Action<string>) {
const query = taintCurrentQuery(state);
delete query.params.measures[action.payload];
Expand Down Expand Up @@ -153,7 +162,7 @@ export const queriesSlice = createSlice({
/**
* Sets the isPreview value for the current QueryItem.
*/
updateIsPreview(state, { payload }: Action<boolean | undefined>) {
updateIsPreview(state, {payload}: Action<boolean | undefined>) {
const query = taintCurrentQuery(state);
query.params.isPreview = payload || false;
},
Expand All @@ -162,20 +171,19 @@ export const queriesSlice = createSlice({
* Sets the value of a boolean in the current QueryItem.
* If the action does not specify a new value, toggles the current value.
*/
updateBoolean(state, { payload }: Action<{ key: string, value?: boolean }>) {
updateBoolean(state, {payload}: Action<{key: string; value?: boolean}>) {
const query = taintCurrentQuery(state);
query.params.booleans[payload.key] = typeof payload.value === "boolean"
? payload.value
: !query.params.booleans[payload.key];
query.params.booleans[payload.key] =
typeof payload.value === "boolean" ? payload.value : !query.params.booleans[payload.key];
},

/**
* Sets a new cube for the current QueryItem, and updates its available measures.
*/
updateCube(state, { payload }: Action<{ cube: string, measures: Record<string, MeasureItem> }>) {
updateCube(state, {payload}: Action<{cube: string; measures: Record<string, MeasureItem>}>) {
const query = taintCurrentQuery(state);
if (payload.cube !== query.params.cube) {
const { params, result } = buildQuery({
const {params, result} = buildQuery({
params: {
cube: payload.cube,
measures: payload.measures,
Expand All @@ -194,31 +202,32 @@ export const queriesSlice = createSlice({
/**
* Replaces a single CutItem in the current QueryItem.
*/
updateCut(state, { payload }: Action<CutItem>) {
updateCut(state, {payload}: Action<CutItem>) {
const query = taintCurrentQuery(state);
query.params.cuts[payload.fullName] = payload;
query.params.cuts[payload.key] = payload;
},

/**
* Replaces a single DrilldownItem in the current QueryItem.
*/
updateDrilldown(state, { payload }: Action<DrilldownItem>) {
updateDrilldown(state, {payload}: Action<DrilldownItem>) {
const query = taintCurrentQuery(state);
query.params.drilldowns[payload.fullName] = payload;
// what
query.params.drilldowns[payload.key] = payload;
},

/**
* Replaces a single FilterItem in the current QueryItem.
*/
updateFilter(state, { payload }: Action<FilterItem>) {
updateFilter(state, {payload}: Action<FilterItem>) {
const query = taintCurrentQuery(state);
query.params.filters[payload.key] = payload;
},

/**
* Replaces the locale setting in the current QueryItem.
*/
updateLocale(state, { payload }: Action<string>) {
updateLocale(state, {payload}: Action<string>) {
const query = state.itemMap[state.current];
if (payload !== query.params.locale) {
// query.isDirty = true;
Expand All @@ -229,15 +238,15 @@ export const queriesSlice = createSlice({
/**
* Replaces a single MeasureItem in the current QueryItem.
*/
updateMeasure(state, { payload }: Action<MeasureItem>) {
updateMeasure(state, {payload}: Action<MeasureItem>) {
const query = taintCurrentQuery(state);
query.params.measures[payload.name] = payload;
},

/**
* Replaces the pagination settings in the current QueryItem.
*/
updatePagination(state, { payload }: Action<{ limit: number, offset: number }>) {
updatePagination(state, {payload}: Action<{limit: number; offset: number}>) {
const query = taintCurrentQuery(state);
query.params.pagiLimit = payload.limit;
query.params.pagiOffset = payload.offset;
Expand All @@ -246,7 +255,7 @@ export const queriesSlice = createSlice({
/**
* Replaces the sorting settings in the current QueryItem.
*/
updateSorting(state, { payload }: Action<{ key: string, dir: "asc" | "desc" }>) {
updateSorting(state, {payload}: Action<{key: string; dir: "asc" | "desc"}>) {
const query = taintCurrentQuery(state);
query.params.sortDir = payload.dir;
query.params.sortKey = payload.key;
Expand All @@ -255,7 +264,7 @@ export const queriesSlice = createSlice({
/**
* Registers the result of the current QueryItem in the store.
*/
updateResult(state, { payload }: Action<QueryResult>) {
updateResult(state, {payload}: Action<QueryResult>) {
const query = state.itemMap[state.current];
query.isDirty = payload.status < 200 || payload.status > 299;
query.result = payload;
Expand Down Expand Up @@ -286,9 +295,8 @@ export function selectQueriesState(state: ExplorerState): QueriesState {
return state[name];
}

export const selectQueryItems = createSelector(
selectQueriesState,
queries => sortByDate(Object.values(queries.itemMap), "created", false)
export const selectQueryItems = createSelector(selectQueriesState, queries =>
sortByDate(Object.values(queries.itemMap), "created", false)
);

export const selectCurrentQueryItem = createSelector(
Expand All @@ -301,10 +309,7 @@ export const selectCurrentQueryParams = createSelector(
query => query.params
);

export const selectCubeName = createSelector(
selectCurrentQueryParams,
params => params.cube
);
export const selectCubeName = createSelector(selectCurrentQueryParams, params => params.cube);

export const selectLocale = createSelector(
[selectCurrentQueryParams, selectServerState],
Expand All @@ -318,10 +323,7 @@ export const selectLocale = createSelector(
}
);

export const selectCutMap = createSelector(
selectCurrentQueryParams,
params => params.cuts
);
export const selectCutMap = createSelector(selectCurrentQueryParams, params => params.cuts);
export const selectCutKeys = createSelector(selectCutMap, getKeys);
export const selectCutItems = createSelector(selectCutMap, getValues<CutItem>);

Expand All @@ -332,40 +334,30 @@ export const selectDrilldownMap = createSelector(
export const selectDrilldownKeys = createSelector(selectDrilldownMap, getKeys);
export const selectDrilldownItems = createSelector(selectDrilldownMap, getValues<DrilldownItem>);

export const selectFilterMap = createSelector(
selectCurrentQueryParams,
params => params.filters
);
export const selectFilterMap = createSelector(selectCurrentQueryParams, params => params.filters);
export const selectFilterKeys = createSelector(selectFilterMap, getKeys);
export const selectFilterItems = createSelector(selectFilterMap, getValues<FilterItem>);

export const selectMeasureMap = createSelector(
selectCurrentQueryParams,
params => params.measures
);
export const selectMeasureMap = createSelector(selectCurrentQueryParams, params => params.measures);
export const selectMeasureKeys = createSelector(selectMeasureMap, getKeys);
export const selectMeasureItems = createSelector(selectMeasureMap, getValues<MeasureItem>);

export const selectBooleans = createSelector(
selectCurrentQueryParams,
params => params.booleans
);
export const selectBooleans = createSelector(selectCurrentQueryParams, params => params.booleans);
export const selectIsPreviewMode = createSelector(
selectCurrentQueryParams,
params => params.isPreview
);

export const selectPaginationParams = createSelector(
selectCurrentQueryParams,
params => ({ limit: params.pagiLimit || 0, offset: params.pagiOffset || 0 })
);
export const selectPaginationParams = createSelector(selectCurrentQueryParams, params => ({
limit: params.pagiLimit || 0,
offset: params.pagiOffset || 0
}));

export const selectSortingParams = createSelector(
selectCurrentQueryParams,
params => ({ sortKey: params.sortKey || "", sortDir: params.sortDir })
);
export const selectSortingParams = createSelector(selectCurrentQueryParams, params => ({
sortKey: params.sortKey || "",
sortDir: params.sortDir
}));

export const selectValidQueryStatus = createSelector(
selectCurrentQueryParams,
params => isValidQueryVerbose(params)
export const selectValidQueryStatus = createSelector(selectCurrentQueryParams, params =>
isValidQueryVerbose(params)
);
Loading

0 comments on commit b1a3b34

Please sign in to comment.