import { DataColumns, DataTableFetchMode } from "~/components/data-table/data-table";
import { DataTableFilters } from '~/components/data-table-filters/data-table-filters-tree';
+export enum DataTableRequestState {
+ IDLE,
+ PENDING,
+ NEED_REFRESH
+}
+
export const dataExplorerActions = unionize({
CLEAR: ofType<{ id: string }>(),
RESET_PAGINATION: ofType<{ id: string }>(),
REQUEST_ITEMS: ofType<{ id: string, criteriaChanged?: boolean }>(),
+ REQUEST_STATE: ofType<{ id: string, criteriaChanged?: boolean }>(),
SET_FETCH_MODE: ofType<({ id: string, fetchMode: DataTableFetchMode })>(),
SET_COLUMNS: ofType<{ id: string, columns: DataColumns<any> }>(),
SET_FILTERS: ofType<{ id: string, columnName: string, filters: DataTableFilters }>(),
TOGGLE_COLUMN: ofType<{ id: string, columnName: string }>(),
TOGGLE_SORT: ofType<{ id: string, columnName: string }>(),
SET_EXPLORER_SEARCH_VALUE: ofType<{ id: string, searchValue: string }>(),
+ SET_REQUEST_STATE: ofType<{ id: string, requestState: DataTableRequestState }>(),
});
export type DataExplorerAction = UnionOf<typeof dataExplorerActions>;
dataExplorerActions.TOGGLE_SORT({ ...payload, id }),
SET_EXPLORER_SEARCH_VALUE: (payload: { searchValue: string }) =>
dataExplorerActions.SET_EXPLORER_SEARCH_VALUE({ ...payload, id }),
+ SET_REQUEST_STATE: (payload: { requestState: DataTableRequestState }) =>
+ dataExplorerActions.SET_REQUEST_STATE({ ...payload, id })
});
return getDataExplorerColumnFilters(columns, columnName);
}
- abstract requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean): void;
+ abstract requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean): Promise<void>;
}
export const getDataExplorerColumnFilters = <T>(columns: DataColumns<T>, columnName: string): DataTableFilters => {
constructor(private config: {
id: string,
columns: DataColumns<any>,
- requestItems: (api: MiddlewareAPI) => void
+ requestItems: (api: MiddlewareAPI) => Promise<void>
}) {
super(config.id);
}
return this.config.columns;
}
- requestItems(api: MiddlewareAPI) {
+ requestItems(api: MiddlewareAPI): Promise<void> {
this.config.requestItems(api);
+ return Promise.resolve();
}
}
//
// SPDX-License-Identifier: AGPL-3.0
+import { Dispatch } from 'redux';
+import { RootState } from '~/store/store';
+import { ServiceRepository } from '~/services/services';
import { Middleware } from "redux";
-import { dataExplorerActions, bindDataExplorerActions } from "./data-explorer-action";
+import { dataExplorerActions, bindDataExplorerActions, DataTableRequestState } from "./data-explorer-action";
+import { getDataExplorer } from "./data-explorer-reducer";
import { DataExplorerMiddlewareService } from "./data-explorer-middleware-service";
export const dataExplorerMiddleware = (service: DataExplorerMiddlewareService): Middleware => api => next => {
api.dispatch(actions.REQUEST_ITEMS(true));
}),
REQUEST_ITEMS: handleAction(({ criteriaChanged }) => {
- service.requestItems(api, criteriaChanged);
+ api.dispatch<any>(async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ while (true) {
+ let de = getDataExplorer(getState().dataExplorer, service.getId());
+ switch (de.requestState) {
+ case DataTableRequestState.IDLE:
+ // Start a new request.
+ try {
+ dispatch(actions.SET_REQUEST_STATE({ requestState: DataTableRequestState.PENDING }));
+ await service.requestItems(api, criteriaChanged);
+ } catch {
+ dispatch(actions.SET_REQUEST_STATE({ requestState: DataTableRequestState.NEED_REFRESH }));
+ }
+ // Now check if the state is still PENDING, if it moved to NEED_REFRESH
+ // then we need to reissue requestItems
+ de = getDataExplorer(getState().dataExplorer, service.getId());
+ const complete = (de.requestState === DataTableRequestState.PENDING);
+ dispatch(actions.SET_REQUEST_STATE({ requestState: DataTableRequestState.IDLE }));
+ if (complete) {
+ return;
+ }
+ break;
+ case DataTableRequestState.PENDING:
+ // State is PENDING, move it to NEED_REFRESH so that when the current request finishes it starts a new one.
+ dispatch(actions.SET_REQUEST_STATE({ requestState: DataTableRequestState.NEED_REFRESH }));
+ return;
+ case DataTableRequestState.NEED_REFRESH:
+ // Nothing to do right now.
+ return;
+ }
+ }
+ });
}),
default: () => next(action)
});
SortDirection,
toggleSortDirection
} from "~/components/data-table/data-column";
-import { DataExplorerAction, dataExplorerActions } from "./data-explorer-action";
+import { DataExplorerAction, dataExplorerActions, DataTableRequestState } from "./data-explorer-action";
import { DataColumns, DataTableFetchMode } from "~/components/data-table/data-table";
import { DataTableFilters } from "~/components/data-table-filters/data-table-filters-tree";
rowsPerPageOptions: number[];
searchValue: string;
working?: boolean;
+ requestState: DataTableRequestState;
}
export const initialDataExplorer: DataExplorer = {
page: 0,
rowsPerPage: 50,
rowsPerPageOptions: [50, 100, 200, 500],
- searchValue: ""
+ searchValue: "",
+ requestState: DataTableRequestState.IDLE
};
export type DataExplorerState = Record<string, DataExplorer>;
SET_EXPLORER_SEARCH_VALUE: ({ id, searchValue }) =>
update(state, id, explorer => ({ ...explorer, searchValue })),
+ SET_REQUEST_STATE: ({ id, requestState }) =>
+ update(state, id, explorer => ({ ...explorer, requestState })),
+
TOGGLE_SORT: ({ id, columnName }) =>
update(state, id, mapColumns(toggleSort(columnName))),
dispatch(projectPanelActions.REQUEST_ITEMS());
dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
};
-
-
import { WebSocketService } from './websocket-service';
import { ResourceEventMessage } from './resource-event-message';
import { ResourceKind } from '~/models/resource';
-import { loadProcess } from '~/store/processes/processes-actions';
-import { loadContainers } from '~/store/processes/processes-actions';
+// import { loadProcess } from '~/store/processes/processes-actions';
+// import { loadContainers } from '~/store/processes/processes-actions';
import { LogEventType } from '~/models/log';
import { addProcessLogsPanelItem } from '../store/process-logs-panel/process-logs-panel-actions';
-import { FilterBuilder } from "~/services/api/filter-builder";
+// import { FilterBuilder } from "~/services/api/filter-builder";
+import { subprocessPanelActions } from "~/store/subprocess-panel/subprocess-panel-actions";
export const initWebSocket = (config: Config, authService: AuthService, store: RootStore) => {
if (config.websocketUrl) {
if (message.eventType === LogEventType.CREATE || message.eventType === LogEventType.UPDATE) {
switch (message.objectKind) {
case ResourceKind.CONTAINER_REQUEST:
- return store.dispatch(loadProcess(message.objectUuid));
+ // return store.dispatch(loadProcess(message.objectUuid));
case ResourceKind.CONTAINER:
- return store.dispatch(loadContainers(
- new FilterBuilder().addIn('uuid', [message.objectUuid]).getFilters()
- ));
+ // return store.dispatch(loadContainers(
+ // new FilterBuilder().addIn('uuid', [message.objectUuid]).getFilters()
+ // ));
+ store.dispatch(subprocessPanelActions.REQUEST_ITEMS());
default:
return;
}
} else {
- return store.dispatch(addProcessLogsPanelItem(message as ResourceEventMessage<{text: string}>));
+ return store.dispatch(addProcessLogsPanelItem(message as ResourceEventMessage<{ text: string }>));
}
};