diff --git a/frontend/app/components/Dashboard/components/DashboardModal/DashboardModal.tsx b/frontend/app/components/Dashboard/components/DashboardModal/DashboardModal.tsx index 055833ee7..027d6b631 100644 --- a/frontend/app/components/Dashboard/components/DashboardModal/DashboardModal.tsx +++ b/frontend/app/components/Dashboard/components/DashboardModal/DashboardModal.tsx @@ -22,11 +22,14 @@ function DashboardModal(props) { const loading = useObserver(() => dashboardStore.isSaving); const onSave = () => { - dashboardStore.save(dashboard).then((_dashboard: any) => { - hideModal(); + dashboardStore.save(dashboard).then(async (_dashboard: any) => { + if (dashboard.exists()) { + await dashboardStore.fetch(dashboard.dashboardId) + } dashboardStore.selectDashboardById(_dashboard.dashboardId).then(() => { history.push(withSiteId(dashboardSelected(_dashboard.dashboardId), siteId)); }); + hideModal(); }) } diff --git a/frontend/app/components/Errors/List/List.js b/frontend/app/components/Errors/List/List.js index 82ecce40c..f75d25e39 100644 --- a/frontend/app/components/Errors/List/List.js +++ b/frontend/app/components/Errors/List/List.js @@ -10,7 +10,6 @@ import Divider from 'Components/Errors/ui/Divider'; import ListItem from './ListItem/ListItem'; import { debounce } from 'App/utils'; -const PER_PAGE = 10; const sortOptionsMap = { 'occurrence-desc': 'Last Occurrence', 'occurrence-desc': 'First Occurrence', @@ -29,6 +28,7 @@ const sortOptions = Object.entries(sortOptionsMap) ignoreLoading: state.getIn([ "errors", "ignore", "loading" ]), mergeLoading: state.getIn([ "errors", "merge", "loading" ]), currentPage: state.getIn(["errors", "currentPage"]), + limit: state.getIn(["errors", "limit"]), total: state.getIn([ 'errors', 'totalCount' ]), sort: state.getIn([ 'errors', 'options', 'sort' ]), order: state.getIn([ 'errors', 'options', 'order' ]), @@ -142,6 +142,7 @@ export default class List extends React.PureComponent { total, sort, order, + limit, } = this.props; const { checkedAll, @@ -224,9 +225,9 @@ export default class List extends React.PureComponent { > { list.map(e => -
+
this.props.updateCurrentPage(page)} - limit={PER_PAGE} + limit={limit} debounceRequest={500} />
diff --git a/frontend/app/duck/errors.js b/frontend/app/duck/errors.js index 2d54b3a0a..4cd236387 100644 --- a/frontend/app/duck/errors.js +++ b/frontend/app/duck/errors.js @@ -42,6 +42,7 @@ const initialState = Map({ stats: Map(), sourcemapUploaded: true, currentPage: 1, + limit: PER_PAGE, options: Map({ sort: DEFAULT_SORT, order: DEFAULT_ORDER, @@ -57,7 +58,7 @@ function reducer(state = initialState, action = {}) { let updError; switch (action.type) { case EDIT_OPTIONS: - return state.mergeIn(["options"], action.instance); + return state.mergeIn(["options"], action.instance).set('currentPage', 1); case success(FETCH): return state.set("instance", ErrorInfo(action.data)); case success(FETCH_TRACE): @@ -68,15 +69,15 @@ function reducer(state = initialState, action = {}) { .set("totalCount", data ? data.total : 0) .set("list", List(data && data.errors).map(ErrorInfo) .filter(e => e.parentErrorId == null) - .map(e => e.update("chart", chartWrapper))); + .map(e => e.update("chart", chartWrapper))) case success(RESOLVE): - updError = { errorId: action.id, status: RESOLVED }; + updError = { errorId: action.id, status: RESOLVED, disabled: true }; return updateItemInList(updateInstance(state, updError), updError); case success(UNRESOLVE): - updError = { errorId: action.id, status: UNRESOLVED }; + updError = { errorId: action.id, status: UNRESOLVED, disabled: true }; return updateItemInList(updateInstance(state, updError), updError); case success(IGNORE): - updError = { errorId: action.id, status: IGNORED }; + updError = { errorId: action.id, status: IGNORED, disabled: true }; return updateItemInList(updateInstance(state, updError), updError); case success(TOGGLE_FAVORITE): return state.mergeIn([ "instance" ], { favorite: !state.getIn([ "instance", "favorite" ]) }) @@ -158,28 +159,43 @@ export function fetchBookmarks() { } } -export function resolve(id) { - return { +export const resolve = (id) => (dispatch, getState) => { + const list = getState().getIn(['errors', 'list']); + const index = list.findIndex(e => e.get('errorId') === id); + const error = list.get(index); + if (error.get('status') === RESOLVED) return; + + return dispatch({ types: array(RESOLVE), id, call: client => client.get(`/errors/${ id }/solve`), - } + }) } -export function unresolve(id) { - return { +export const unresolve = (id) => (dispatch, getState) => { + const list = getState().getIn(['errors', 'list']); + const index = list.findIndex(e => e.get('errorId') === id); + const error = list.get(index); + if (error.get('status') === UNRESOLVED) return; + + return dispatch({ types: array(UNRESOLVE), id, call: client => client.get(`/errors/${ id }/unsolve`), - } + }) } -export function ignore(id) { - return { +export const ignore = (id) => (dispatch, getState) => { + const list = getState().getIn(['errors', 'list']); + const index = list.findIndex(e => e.get('errorId') === id); + const error = list.get(index); + if (error.get('status') === IGNORED) return; + + return dispatch({ types: array(IGNORE), id, call: client => client.get(`/errors/${ id }/ignore`), - } + }) } export function merge(ids) { diff --git a/frontend/app/mstore/dashboardStore.ts b/frontend/app/mstore/dashboardStore.ts index 65dcaf82b..e19757ee6 100644 --- a/frontend/app/mstore/dashboardStore.ts +++ b/frontend/app/mstore/dashboardStore.ts @@ -355,30 +355,25 @@ export default class DashboardStore implements IDashboardSotre { fetchTemplates(): Promise { return new Promise((resolve, reject) => { - if (this.widgetCategories.length > 0) { - resolve(this.widgetCategories) - } else { - metricService.getTemplates().then(response => { - const categories: any[] = [] - response.forEach(category => { - const widgets: any[] = [] - // TODO speed_location is not supported yet - category.widgets.filter(w => w.predefinedKey !== 'speed_locations').forEach(widget => { - const w = new Widget().fromJson(widget) - widgets.push(w) - }) - const c: any = {} - c.widgets = widgets - c.name = category.category - c.description = category.description - categories.push(c) + metricService.getTemplates().then(response => { + const categories: any[] = [] + response.forEach(category => { + const widgets: any[] = [] + category.widgets.filter(w => w.predefinedKey !== 'speed_locations').forEach(widget => { + const w = new Widget().fromJson(widget) + widgets.push(w) }) - this.widgetCategories = categories - resolve(this.widgetCategories) - }).catch(error => { - reject(error) + const c: any = {} + c.widgets = widgets + c.name = category.category + c.description = category.description + categories.push(c) }) - } + this.widgetCategories = categories + resolve(this.widgetCategories) + }).catch(error => { + reject(error) + }) }) } diff --git a/frontend/app/types/errorInfo.js b/frontend/app/types/errorInfo.js index 364fa8e65..db4c2f3a0 100644 --- a/frontend/app/types/errorInfo.js +++ b/frontend/app/types/errorInfo.js @@ -37,6 +37,7 @@ const ErrorInfo = Record({ chart30: [], tags: [], lastHydratedSession: Session(), + disabled: false, }, { fromJS: ({ stack, lastHydratedSession, ...other }) => ({ ...other,