diff --git a/.version b/.version index 3f8dcd03d2..8eb5b22f25 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.13.2 \ No newline at end of file +0.13.3 \ No newline at end of file diff --git a/frontend/src/Editor/ActionTypes.js b/frontend/src/Editor/ActionTypes.js index 48528fbc5d..ecd238ed76 100644 --- a/frontend/src/Editor/ActionTypes.js +++ b/frontend/src/Editor/ActionTypes.js @@ -54,4 +54,16 @@ export const ActionTypes = [ { name: 'data', type: 'code', default: '{{[]}}' }, ], }, + { + name: 'Set table page', + id: 'set-table-page', + options: [ + { + name: 'table', + type: 'text', + default: '', + }, + { name: 'pageIndex', type: 'text', default: '{{1}}' }, + ], + }, ]; diff --git a/frontend/src/Editor/Box.jsx b/frontend/src/Editor/Box.jsx index a6f38777ef..d54ead043a 100644 --- a/frontend/src/Editor/Box.jsx +++ b/frontend/src/Editor/Box.jsx @@ -174,6 +174,7 @@ export const Box = function Box({ exposedVariables={exposedVariables} styles={resolvedStyles} setExposedVariable={(variable, value) => onComponentOptionChanged(component, variable, value, extraProps)} + registerAction={(actionName, func) => onComponentOptionChanged(component, actionName, func)} fireEvent={fireEvent} validate={validate} parentId={parentId} diff --git a/frontend/src/Editor/Components/Table/Pagination.jsx b/frontend/src/Editor/Components/Table/Pagination.jsx index dcf343ba25..c545c61eb0 100644 --- a/frontend/src/Editor/Components/Table/Pagination.jsx +++ b/frontend/src/Editor/Components/Table/Pagination.jsx @@ -8,8 +8,9 @@ export const Pagination = function Pagination({ autoPageCount, autoPageOptions, lastActivePageIndex, + pageIndex, + setPageIndex, }) { - const [pageIndex, setPageIndex] = useState(lastActivePageIndex ?? 1); const [pageCount, setPageCount] = useState(autoPageCount); useEffect(() => { diff --git a/frontend/src/Editor/Components/Table/Table.jsx b/frontend/src/Editor/Components/Table/Table.jsx index b46825c73a..a6e036df77 100644 --- a/frontend/src/Editor/Components/Table/Table.jsx +++ b/frontend/src/Editor/Components/Table/Table.jsx @@ -39,6 +39,7 @@ export function Table({ onComponentOptionsChanged, darkMode, fireEvent, + registerAction, }) { const color = component.definition.styles.textColor.value; const actions = component.definition.properties.actions || { value: [] }; @@ -758,6 +759,14 @@ export function Table({ } ); + useEffect(() => { + registerAction('setPage', (targetPageIndex) => { + setPaginationInternalPageIndex(targetPageIndex); + onPageIndexChanged(targetPageIndex); + if (!serverSidePagination && clientSidePagination) gotoPage(targetPageIndex - 1); + }); + }, [serverSidePagination, clientSidePagination]); + useEffect(() => { const selectedRowsOriginalData = selectedFlatRows.map((row) => row.original); onComponentOptionChanged(component, 'selectedRows', selectedRowsOriginalData); @@ -790,6 +799,8 @@ export function Table({ } }, [state.columnResizing.isResizingColumn]); + const [paginationInternalPageIndex, setPaginationInternalPageIndex] = useState(pageIndex ?? 1); + useEffect(() => { if (pageCount <= pageIndex) gotoPage(pageCount - 1); }, [pageCount]); @@ -936,6 +947,8 @@ export function Table({ autoPageCount={pageCount} autoPageOptions={pageOptions} onPageIndexChanged={onPageIndexChanged} + pageIndex={paginationInternalPageIndex} + setPageIndex={setPaginationInternalPageIndex} /> )} diff --git a/frontend/src/Editor/Components/components.js b/frontend/src/Editor/Components/components.js index 3960050d37..94de0ae03d 100644 --- a/frontend/src/Editor/Components/components.js +++ b/frontend/src/Editor/Components/components.js @@ -64,7 +64,7 @@ export const componentTypes = [ selectedRow: {}, changeSet: {}, dataUpdates: [], - pageIndex: 0, + pageIndex: 1, searchText: '', selectedRows: [], }, diff --git a/frontend/src/Editor/Editor.jsx b/frontend/src/Editor/Editor.jsx index 55b5c81407..a850c55d13 100644 --- a/frontend/src/Editor/Editor.jsx +++ b/frontend/src/Editor/Editor.jsx @@ -55,6 +55,7 @@ class Editor extends React.Component { email: currentUser.email, firstName: currentUser.first_name, lastName: currentUser.last_name, + groups: currentUser?.group_permissions.map((group) => group.group), }; } diff --git a/frontend/src/Editor/Inspector/EventManager.jsx b/frontend/src/Editor/Inspector/EventManager.jsx index a5ce263fd6..9acf254b06 100644 --- a/frontend/src/Editor/Inspector/EventManager.jsx +++ b/frontend/src/Editor/Inspector/EventManager.jsx @@ -59,18 +59,17 @@ export const EventManager = ({ }; }); - function getModalOptions() { - let modalOptions = []; + function getComponentOptions(componentType) { + let componentOptions = []; Object.keys(components || {}).forEach((key) => { - if (components[key].component.component === 'Modal') { - modalOptions.push({ + if (components[key].component.component === componentType) { + componentOptions.push({ name: components[key].component.name, - value: key, + value: { name: components[key].component.name, id: key }, }); } }); - - return modalOptions; + return componentOptions; } function getAllApps() { @@ -207,7 +206,7 @@ export const EventManager = ({
Modal
{ @@ -225,7 +224,7 @@ export const EventManager = ({
Modal
{ @@ -340,6 +339,37 @@ export const EventManager = ({
)} + {event.actionId === 'set-table-page' && ( + <> +
+
Table
+
+ { + handlerChanged(index, 'table', value); + }} + filterOptions={fuzzySearch} + placeholder="Select.." + /> +
+
+
+
Page index
+
+ handlerChanged(index, 'pageIndex', value)} + enablePreview={true} + usePortalEditor={false} + /> +
+
+ + )}
diff --git a/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx b/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx index 15145439ff..bad0a99520 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx @@ -63,7 +63,7 @@ export const LeftSidebarInspector = ({ darkMode, globals, components, queries }) collapsed={true} displayObjectSize={false} quotesOnKeys={false} - sortKeys={true} + sortKeys={false} // indentWidth={1} /> diff --git a/frontend/src/Editor/Viewer.jsx b/frontend/src/Editor/Viewer.jsx index 10fef8f2c4..d4773a8237 100644 --- a/frontend/src/Editor/Viewer.jsx +++ b/frontend/src/Editor/Viewer.jsx @@ -17,6 +17,7 @@ import { import queryString from 'query-string'; import { DarkModeToggle } from '@/_components/DarkModeToggle'; import LogoIcon from './Icons/logo.svg'; +import { DataSourceTypes } from './DataSourceManager/SourceComponents'; class Viewer extends React.Component { constructor(props) { @@ -72,6 +73,14 @@ class Viewer extends React.Component { ).length > 0; } + let queryState = {}; + data.data_queries.forEach((query) => { + queryState[query.name] = { + ...DataSourceTypes.find((source) => source.kind === query.kind).exposedVariables, + ...this.state.currentState.queries[query.name], + }; + }); + this.setState( { currentSidebarTab: 2, @@ -84,7 +93,7 @@ class Viewer extends React.Component { : '1292px', selectedComponent: null, currentState: { - queries: {}, + queries: queryState, components: {}, globals: { current_user: userVars, diff --git a/frontend/src/_helpers/appUtils.js b/frontend/src/_helpers/appUtils.js index 80969fd8c8..f0925930d8 100644 --- a/frontend/src/_helpers/appUtils.js +++ b/frontend/src/_helpers/appUtils.js @@ -21,6 +21,17 @@ export function setStateAsync(_ref, state) { }); } +export function setCurrentStateAsync(_ref, changes) { + return new Promise((resolve) => { + _ref.setState((prevState) => { + return { + currentState: prevState.currentState, + ...changes, + }; + }, resolve); + }); +} + export function onComponentOptionsChanged(_ref, component, options) { const componentName = component.name; const components = _ref.state.currentState.components; @@ -43,9 +54,7 @@ export function onComponentOptionChanged(_ref, component, option_name, value) { componentData = componentData || {}; componentData[option_name] = value; - return setStateAsync(_ref, { - currentState: { ..._ref.state.currentState, components: { ...components, [componentName]: componentData } }, - }); + return setCurrentStateAsync(_ref, { components: { ...components, [componentName]: componentData } }); } export function fetchOAuthToken(authUrl, dataSourceId) { @@ -105,7 +114,8 @@ async function copyToClipboard(text) { } } -function showModal(_ref, modalId, show) { +function showModal(_ref, modal, show) { + const modalId = modal.id; if (_.isEmpty(modalId)) { console.log('No modal is associated with this event.'); return Promise.resolve(); @@ -228,6 +238,10 @@ function executeAction(_ref, event, mode) { generateFile(fileName, csv); return Promise.resolve(); } + + case 'set-table-page': { + setTablePageIndex(_ref, event.table, event.pageIndex); + } } } } @@ -671,6 +685,18 @@ export function runQuery(_ref, queryId, queryName, confirmed = undefined, mode) }); } +function setTablePageIndex(_ref, table, index) { + if (_.isEmpty(table.id)) { + console.log('No table is associated with this event.'); + return Promise.resolve(); + } + + const tableMeta = _ref.state.currentState.components[table.name]; + const newPageIndex = resolveReferences(index, _ref.state.currentState); + tableMeta.setPage(newPageIndex); + return Promise.resolve(); +} + export function renderTooltip({ props, text }) { return (