}
inline={true}
fill={true}>
+ {...getFieldProps('name')} />
@@ -183,7 +234,7 @@ function ViewForm({
Define the conditionals
- {formik.values.roles.map((role, index) => (
+ {values.roles.map((role, index) => (
{ index + 1 }
@@ -196,38 +247,36 @@ function ViewForm({
-
+ intent={hasError(`roles[${index}].field_key`) && Intent.DANGER}>
+ {...getFieldProps(`roles[${index}].field_key`)} />
-
+ intent={hasError(`roles[${index}].comparator`) && Intent.DANGER}>
+ {...getFieldProps(`roles[${index}].comparator`)} />
-
+
+ {...getFieldProps(`roles[${index}].value`)} />
}
+ icon={}
iconSize={14}
className="ml2"
minimal={true}
@@ -237,12 +286,12 @@ function ViewForm({
))}
-
+
@@ -252,22 +301,24 @@ function ViewForm({
}
inline={true}
fill={true}>
-
+
-
+
Columns Preferences
-
+
Available Columns
@@ -317,11 +368,22 @@ function ViewForm({
@@ -331,4 +393,6 @@ function ViewForm({
export default compose(
ViewFormConnect,
+ DashboardConnect,
+ ResourceConnect,
)(ViewForm);
\ No newline at end of file
diff --git a/client/src/connectors/Resource.connector.js b/client/src/connectors/Resource.connector.js
index eee66fa20..51575cbd0 100644
--- a/client/src/connectors/Resource.connector.js
+++ b/client/src/connectors/Resource.connector.js
@@ -6,11 +6,16 @@ import {
import {
getResourceColumns,
getResourceFields,
+ getResourceColumn,
+ getResourceField,
} from 'store/resources/resources.reducer';
export const mapStateToProps = (state, props) => ({
getResourceColumns: (resourceSlug) => getResourceColumns(state, resourceSlug),
getResourceFields: (resourceSlug) => getResourceFields(state, resourceSlug),
+
+ getResourceColumn: (columnId) => getResourceColumn(state, columnId),
+ getResourceField: (fieldId) => getResourceField(state, fieldId),
});
export const mapDispatchToProps = (dispatch) => ({
diff --git a/client/src/connectors/ViewFormPage.connector.js b/client/src/connectors/ViewFormPage.connector.js
index ea0c1c535..c8d44d3af 100644
--- a/client/src/connectors/ViewFormPage.connector.js
+++ b/client/src/connectors/ViewFormPage.connector.js
@@ -16,18 +16,11 @@ import t from 'store/types';
export const mapStateToProps = (state, props) => {
return {
- getResourceColumns: (resourceSlug) => getResourceColumns(state, resourceSlug),
- getResourceFields: (resourceSlug) => getResourceFields(state, resourceSlug),
+
};
};
export const mapDispatchToProps = (dispatch) => ({
- changePageTitle: pageTitle => dispatch({
- type: t.CHANGE_DASHBOARD_PAGE_TITLE,
- pageTitle,
- }),
- fetchResourceFields: (resourceSlug) => dispatch(fetchResourceFields({ resourceSlug })),
- fetchResourceColumns: (resourceSlug) => dispatch(fetchResourceColumns({ resourceSlug })),
fetchView: (id) => dispatch(fetchView({ id })),
submitView: (form) => dispatch(submitView({ form })),
editView: (id, form) => dispatch(editView({ id, form })),
diff --git a/client/src/containers/Dashboard/Views/ViewFormPage.js b/client/src/containers/Dashboard/Views/ViewFormPage.js
index fb1469e6e..fdfb1993e 100644
--- a/client/src/containers/Dashboard/Views/ViewFormPage.js
+++ b/client/src/containers/Dashboard/Views/ViewFormPage.js
@@ -1,6 +1,6 @@
-import React, {useEffect, useState} from 'react';
+import React, {useEffect, useState, useCallback} from 'react';
import { useAsync } from 'react-use';
-import { useParams } from 'react-router-dom';
+import { useParams, useHistory } from 'react-router-dom';
import { Intent, Alert } from '@blueprintjs/core';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
@@ -23,8 +23,10 @@ function ViewFormPage({
deleteView,
}) {
const { resource_slug: resourceSlug, view_id: viewId } = useParams();
+
const columns = getResourceColumns('accounts');
const fields = getResourceFields('accounts');
+
const viewForm = (viewId) ? getViewMeta(viewId) : null;
const [stateDeleteView, setStateDeleteView] = useState(null);
@@ -35,7 +37,7 @@ function ViewFormPage({
} else {
changePageTitle('New Custom View');
}
- }, [viewId]);
+ }, [viewId, changePageTitle]);
const fetchHook = useAsync(async () => {
await Promise.all([
@@ -47,21 +49,28 @@ function ViewFormPage({
]);
}, []);
- const handleDeleteView = (view) => { setStateDeleteView(view); };
- const handleCancelDeleteView = () => { setStateDeleteView(null); };
+ const handleDeleteView = useCallback((view) => {
+ setStateDeleteView(view);
+ }, []);
- const handleConfirmDeleteView = () => {
+ const handleCancelDeleteView = useCallback(() => {
+ setStateDeleteView(null);
+ }, []);
+
+ const handleConfirmDeleteView = useCallback(() => {
deleteView(stateDeleteView.id).then((response) => {
setStateDeleteView(null);
AppToaster.show({
message: 'the_custom_view_has_been_deleted',
});
})
- };
+ }, [deleteView, stateDeleteView]);
+
return (
-
+
{
};
export const editView = ({ id, form }) => {
- return (dispatch) => ApiService.post(`views/${id}`);
+ return (dispatch) => ApiService.post(`views/${id}`, form);
};
export const deleteView = ({ id }) => {
diff --git a/client/src/store/resources/resources.reducer.js b/client/src/store/resources/resources.reducer.js
index 752650450..4d43fee43 100644
--- a/client/src/store/resources/resources.reducer.js
+++ b/client/src/store/resources/resources.reducer.js
@@ -1,22 +1,41 @@
import { createReducer } from "@reduxjs/toolkit";
import t from 'store/types';
+import { pickItemsFromIds } from 'store/selectors'
const initialState = {
- resourceFields: {
- // resource name => { field_id }
- },
+ fields: {},
+ columns: {},
+ resourceFields: {},
resourceColumns: {},
};
export default createReducer(initialState, {
[t.RESOURCE_COLUMNS_SET]: (state, action) => {
- state.resourceColumns[action.resource_slug] = action.columns;
+ const _columns = {};
+
+ action.columns.forEach((column) => {
+ _columns[column.id] = column;
+ });
+ state.columns = {
+ ...state.columns,
+ ..._columns,
+ };
+ state.resourceColumns[action.resource_slug] = action.columns.map(c => c.id);
},
[t.RESOURCE_FIELDS_SET]: (state, action) => {
- state.resourceFields[action.resource_slug] = action.fields;
+ const _fields = {};
+
+ action.fields.forEach((field) => {
+ _fields[field.id] = field;
+ });
+ state.fields = {
+ ...state.fields,
+ ..._fields,
+ };
+ state.resourceFields[action.resource_slug] = action.fields.map(f => f.id);
},
-})
+});
/**
* Retrieve resource fields of the given resource slug.
@@ -24,9 +43,10 @@ export default createReducer(initialState, {
* @param {String} resourceSlug
*/
export const getResourceFields = (state, resourceSlug) => {
- const resourceFields = state.resources.resourceFields[resourceSlug];
- return resourceFields ? Object.values(resourceFields) : [];
-}
+ const resourceIds = state.resources.resourceFields[resourceSlug];
+ const items = state.resources.fields;
+ return pickItemsFromIds(items, resourceIds);
+};
/**
* Retrieve resource columns of the given resource slug.
@@ -34,6 +54,25 @@ export const getResourceFields = (state, resourceSlug) => {
* @param {String} resourceSlug -
*/
export const getResourceColumns = (state, resourceSlug) => {
- const resourceColumns = state.resources.resourceColumns[resourceSlug];
- return resourceColumns ? Object.values(resourceColumns) : [];
-}
\ No newline at end of file
+ const resourceIds = state.resources.resourceColumns[resourceSlug];
+ const items = state.resources.columns;
+ return pickItemsFromIds(items, resourceIds);
+};
+
+/**
+ *
+ * @param {State} state
+ * @param {Number} fieldId
+ */
+export const getResourceField = (state, fieldId) => {
+ return state.resources.fields[fieldId];
+};
+
+/**
+ *
+ * @param {State} state
+ * @param {Number} columnId
+ */
+export const getResourceColumn = (state, columnId) => {
+ return state.resources.columns[columnId];
+};
\ No newline at end of file
diff --git a/client/src/style/components/data-table.scss b/client/src/style/components/data-table.scss
index 372a17252..4d9310a4f 100644
--- a/client/src/style/components/data-table.scss
+++ b/client/src/style/components/data-table.scss
@@ -134,6 +134,14 @@
background-color: #CFDCEE;
}
}
+ .tr.no-results{
+ .td{
+ flex-direction: column;
+ padding: 20px;
+ color: #666;
+ align-items: center;
+ }
+ }
}
.tr .th.expander,
diff --git a/client/src/style/objects/form.scss b/client/src/style/objects/form.scss
index 5efc41023..11928ac19 100644
--- a/client/src/style/objects/form.scss
+++ b/client/src/style/objects/form.scss
@@ -80,12 +80,12 @@ $form-check-input-indeterminate-bg-image: url("data:image/svg+xml,