Commit 0f49c032 authored by Florent Chehab's avatar Florent Chehab
Browse files

userdata retreival and post operationnal !

Many bugs corrected !
Few tweaks
parent c0c08869
Pipeline #26965 failed with stages
in 2 minutes and 18 seconds
...@@ -23,11 +23,10 @@ class UserDataSerializer(MyModelSerializer): ...@@ -23,11 +23,10 @@ class UserDataSerializer(MyModelSerializer):
owner = serializers.CharField(read_only=True) owner = serializers.CharField(read_only=True)
def my_pre_save(self): def my_pre_save(self):
user = self.get_user_in_request() self.override_validated_data({'owner': self.user})
self.override_validated_data({'owner': user})
# we try to recover the correct instance # we try to recover the correct instance
query = UserData.objects.filter(owner=user) query = UserData.objects.filter(owner=self.user)
if len(query) == 1: if len(query) == 1:
self.instance = query[0] self.instance = query[0]
...@@ -39,6 +38,7 @@ class UserDataSerializer(MyModelSerializer): ...@@ -39,6 +38,7 @@ class UserDataSerializer(MyModelSerializer):
class UserDataViewSet(MyModelViewSet): class UserDataViewSet(MyModelViewSet):
permission_classes = get_viewset_permissions("UserDataViewSet") permission_classes = get_viewset_permissions("UserDataViewSet")
serializer_class = UserDataSerializer serializer_class = UserDataSerializer
BYPASS_DICT_MODE = True
def get_queryset(self): def get_queryset(self):
return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101 return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101
...@@ -10,19 +10,19 @@ ...@@ -10,19 +10,19 @@
// {{obj.NAME}} // {{obj.NAME}}
//////////////// ////////////////
export const {{obj.NAME}}_HAS_ERROR = '{{obj.NAME}}_HAS_ERROR'; export const {{obj.NAME}}_FETCH_HAS_ERROR = '{{obj.NAME}}_FETCH_HAS_ERROR';
export const {{obj.NAME}}_IS_LOADING = '{{obj.NAME}}_IS_LOADING'; export const {{obj.NAME}}_IS_LOADING = '{{obj.NAME}}_IS_LOADING';
export const {{obj.NAME}}_FETCH_DATA_SUCCESS = '{{obj.NAME}}_FETCH_DATA_SUCCESS'; export const {{obj.NAME}}_FETCH_DATA_SUCCESS = '{{obj.NAME}}_FETCH_DATA_SUCCESS';
export const {{obj.NAME}}_INVALIDATED = '{{obj.NAME}}_INVALIDATED'; export const {{obj.NAME}}_INVALIDATED = '{{obj.NAME}}_INVALIDATED';
export const {{obj.NAME}}_EL_HAS_ERROR = '{{obj.NAME}}_HAS_ERROR'; export const {{obj.NAME}}_EL_FETCH_HAS_ERROR = '{{obj.NAME}}_EL_FETCH_HAS_ERROR';
export const {{obj.NAME}}_EL_INVALIDATED = '{{obj.NAME}}_EL_INVALIDATED'; export const {{obj.NAME}}_EL_INVALIDATED = '{{obj.NAME}}_EL_INVALIDATED';
export const {{obj.NAME}}_EL_IS_LOADING = '{{obj.NAME}}_IS_LOADING'; export const {{obj.NAME}}_EL_IS_LOADING = '{{obj.NAME}}_EL_IS_LOADING';
export const {{obj.NAME}}_EL_FETCH_DATA_SUCCESS = '{{obj.NAME}}_FETCH_DATA_SUCCESS'; export const {{obj.NAME}}_EL_FETCH_DATA_SUCCESS = '{{obj.NAME}}_EL_FETCH_DATA_SUCCESS';
{% if not obj.read_only %} {% if not obj.read_only %}
export const {{obj.NAME}}_EL_IS_SAVING = '{{obj.NAME}}_IS_POSTING'; export const {{obj.NAME}}_EL_IS_SAVING = '{{obj.NAME}}_EL_IS_SAVING';
export const {{obj.NAME}}_EL_SAVING_DATA_SUCCESS = '{{obj.NAME}}_POST_DATA_SUCCESS'; export const {{obj.NAME}}_EL_SAVING_HAS_ERROR = '{{obj.NAME}}_EL_SAVING_HAS_ERROR';
{% endif %} {% endif %}
{% endfor %} {% endfor %}
...@@ -8,18 +8,19 @@ import Cookies from 'js-cookie'; ...@@ -8,18 +8,19 @@ import Cookies from 'js-cookie';
import { import {
{% for obj in data %} {% for obj in data %}
{{obj.NAME}}_HAS_ERROR, {{obj.NAME}}_FETCH_HAS_ERROR,
{{obj.NAME}}_IS_LOADING, {{obj.NAME}}_IS_LOADING,
{{obj.NAME}}_FETCH_DATA_SUCCESS, {{obj.NAME}}_FETCH_DATA_SUCCESS,
{{obj.NAME}}_INVALIDATED, {{obj.NAME}}_INVALIDATED,
{{obj.NAME}}_EL_INVALIDATED, {{obj.NAME}}_EL_INVALIDATED,
{{obj.NAME}}_EL_HAS_ERROR, {{obj.NAME}}_EL_FETCH_HAS_ERROR,
{{obj.NAME}}_EL_IS_LOADING, {{obj.NAME}}_EL_IS_LOADING,
{{obj.NAME}}_EL_FETCH_DATA_SUCCESS, {{obj.NAME}}_EL_FETCH_DATA_SUCCESS,
{% if not obj.read_only %} {% if not obj.read_only %}
{{obj.NAME}}_EL_IS_SAVING, {{obj.NAME}}_EL_IS_SAVING,
{{obj.NAME}}_EL_SAVING_HAS_ERROR,
{{obj.NAME}}_EL_SAVING_DATA_SUCCESS, {{obj.NAME}}_EL_SAVING_DATA_SUCCESS,
{% endif %} {% endif %}
...@@ -30,9 +31,12 @@ import { ...@@ -30,9 +31,12 @@ import {
// generic function definitions // generic function definitions
function _FetchData(pk, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidated, _HasError, pk_required=false) { function _FetchData(pk, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidated, _HasError, pk_required=false) {
if (pk_required && pk == ""){ if (pk_required && (typeof pk == 'undefined')){
throw "pk shouldn't be empty when requesting a specific element"; throw "pk shouldn't be empty when requesting a specific element";
} }
if (pk != ""){
api_end_point += pk;
}
return (dispatch) => { return (dispatch) => {
dispatch(_IsLoading(true)); dispatch(_IsLoading(true));
let token = Cookies.get('csrftoken'); let token = Cookies.get('csrftoken');
...@@ -49,13 +53,16 @@ function _FetchData(pk, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidat ...@@ -49,13 +53,16 @@ function _FetchData(pk, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidat
dispatch(_FetchDataSuccess(obj)); dispatch(_FetchDataSuccess(obj));
dispatch(_IsLoading(false)); dispatch(_IsLoading(false));
}) })
.catch(() => dispatch(_HasError(true))); .catch((e) => {
dispatch(_HasError(true, e));
dispatch(_IsLoading(false));
});
}; };
} }
function _ElSaveData(data, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidated, _HasError) { function _ElSaveData(data, api_end_point, _ElIsSaving, _ElFetchDataSuccess, _ElInvalidated, _ElHasError) {
return (dispatch) => { return (dispatch) => {
let method = "POST"; let method = "POST";
let pk = ""; let pk = "";
...@@ -86,20 +93,24 @@ function _ElSaveData(data, api_end_point, _IsLoading, _FetchDataSuccess, _Invali ...@@ -86,20 +93,24 @@ function _ElSaveData(data, api_end_point, _IsLoading, _FetchDataSuccess, _Invali
.then((response) => response.json()) .then((response) => response.json())
.then((_El) => { .then((_El) => {
dispatch(_ElInvalidated(false)); dispatch(_ElInvalidated(false));
dispatch(_ElSaveDataSuccess(_El)); dispatch(_ElFetchDataSuccess(_El)); // we use the same here
dispatch(_ElIsSaving(false)); dispatch(_ElIsSaving(false));
}) })
.catch(() => dispatch(_ElHasError(true))); .catch((e) => {
dispatch(_ElHasError(true, e))
dispatch(_ElIsSaving(false));
});
}; };
} }
///////////////////////////////// /////////////////////////////////
{% for obj in data %} {% for obj in data %}
export function {{obj.name}}HasError(bool) { export function {{obj.name}}FetchHasError(bool, error=null) {
return { return {
type: {{obj.NAME}}_HAS_ERROR, type: {{obj.NAME}}_FETCH_HAS_ERROR,
hasError: bool hasError: bool,
error
}; };
} }
...@@ -135,15 +146,16 @@ export function {{obj.name}}FetchData() { ...@@ -135,15 +146,16 @@ export function {{obj.name}}FetchData() {
{{obj.name}}IsLoading, {{obj.name}}IsLoading,
{{obj.name}}FetchDataSuccess, {{obj.name}}FetchDataSuccess,
{{obj.name}}Invalidated, {{obj.name}}Invalidated,
{{obj.name}}HasError {{obj.name}}FetchHasError
) )
} }
export function {{obj.name}}ElHasError(bool) { export function {{obj.name}}ElFetchHasError(bool, error) {
return { return {
type: {{obj.NAME}}_EL_HAS_ERROR, type: {{obj.NAME}}_EL_FETCH_HAS_ERROR,
hasError: bool hasError: bool,
error
}; };
} }
...@@ -180,7 +192,7 @@ export function {{obj.name}}ElFetchData(pk) { ...@@ -180,7 +192,7 @@ export function {{obj.name}}ElFetchData(pk) {
{{obj.name}}ElIsLoading, {{obj.name}}ElIsLoading,
{{obj.name}}ElFetchDataSuccess, {{obj.name}}ElFetchDataSuccess,
{{obj.name}}ElInvalidated, {{obj.name}}ElInvalidated,
{{obj.name}}ElHasError, {{obj.name}}ElFetchHasError,
true true
) )
} }
...@@ -195,19 +207,17 @@ export function {{obj.name}}ElIsSaving(bool) { ...@@ -195,19 +207,17 @@ export function {{obj.name}}ElIsSaving(bool) {
}; };
} }
export function {{obj.name}}ElSavingHasError(bool, error=null) {
export function {{obj.name}}ElSaveDataSuccess({{obj.name}}El) {
{{obj.name}}ElInvalidated(false)
return { return {
type: {{obj.NAME}}_EL_SAVING_DATA_SUCCESS, type: {{obj.NAME}}_EL_SAVING_HAS_ERROR,
{{obj.name}}El, hasError: bool,
{{obj.name}}ElSavedAt: Date.now() error
}; };
} }
export function {{obj.name}}ElSaveData(data) { export function {{obj.name}}ElSaveData(data) {
return _ElSaveData(data, "{{obj.api_end_point}}", {{obj.name}}ElIsLoading, {{obj.name}}ElFetchDataSuccess, {{obj.name}}ElInvalidated, {{obj.name}}ElHasError) return _ElSaveData(data, "{{obj.api_end_point}}", {{obj.name}}ElIsSaving, {{obj.name}}ElFetchDataSuccess, {{obj.name}}ElInvalidated, {{obj.name}}ElSavingHasError)
} }
{% endif %} {% endif %}
......
...@@ -9,18 +9,18 @@ import { combineReducers } from 'redux'; ...@@ -9,18 +9,18 @@ import { combineReducers } from 'redux';
import { import {
{% for obj in data %} {% for obj in data %}
{{obj.name}}Invalidated, {{obj.name}}Invalidated,
{{obj.name}}HasError, {{obj.name}}FetchHasError,
{{obj.name}}IsLoading, {{obj.name}}IsLoading,
{{obj.name}}Fetched, {{obj.name}}Fetched,
{{obj.name}}ElInvalidated, {{obj.name}}ElInvalidated,
{{obj.name}}ElHasError, {{obj.name}}ElFetchHasError,
{{obj.name}}ElIsLoading, {{obj.name}}ElIsLoading,
{{obj.name}}ElFetched, {{obj.name}}ElFetched,
{% if not obj.read_only %} {% if not obj.read_only %}
{{obj.name}}ElIsSaving, {{obj.name}}ElIsSaving,
{{obj.name}}ElSaved, {{obj.name}}ElSavingHasError,
{% endif %} {% endif %}
{% endfor %} {% endfor %}
...@@ -29,25 +29,21 @@ import { ...@@ -29,25 +29,21 @@ import {
{% for obj in data %} {% for obj in data %}
export const {{obj.name}}Reducers = combineReducers({ export const {{obj.name}}Reducers = combineReducers({
invalidated: {{obj.name}}Invalidated, invalidated: {{obj.name}}Invalidated,
hasError: {{obj.name}}HasError, fetchHasError: {{obj.name}}FetchHasError,
isLoading: {{obj.name}}IsLoading, isLoading: {{obj.name}}IsLoading,
fetched: {{obj.name}}Fetched, fetched: {{obj.name}}Fetched,
}) })
export const {{obj.name}}ElReducers = combineReducers({ export const {{obj.name}}ElReducers = combineReducers({
invalidated: {{obj.name}}ElInvalidated, invalidated: {{obj.name}}ElInvalidated,
hasError: {{obj.name}}ElHasError, fetchHasError: {{obj.name}}ElFetchHasError,
isLoading: {{obj.name}}ElIsLoading, isLoading: {{obj.name}}ElIsLoading,
fetched: {{obj.name}}ElFetched, fetched: {{obj.name}}ElFetched,
{% if not obj.read_only %} {% if not obj.read_only %}
isSaving: {{obj.name}}ElIsSaving, isSaving: {{obj.name}}ElIsSaving,
isSaved: {{obj.name}}ElSaved, savingHasError: {{obj.name}}ElSavingHasError
{% endif %} {% endif %}
}) })
{% endfor %} {% endfor %}
...@@ -7,17 +7,18 @@ ...@@ -7,17 +7,18 @@
import { import {
{% for obj in data %} {% for obj in data %}
{{obj.NAME}}_INVALIDATED, {{obj.NAME}}_INVALIDATED,
{{obj.NAME}}_HAS_ERROR, {{obj.NAME}}_FETCH_HAS_ERROR,
{{obj.NAME}}_IS_LOADING, {{obj.NAME}}_IS_LOADING,
{{obj.NAME}}_FETCH_DATA_SUCCESS, {{obj.NAME}}_FETCH_DATA_SUCCESS,
{{obj.NAME}}_EL_INVALIDATED, {{obj.NAME}}_EL_INVALIDATED,
{{obj.NAME}}_EL_HAS_ERROR, {{obj.NAME}}_EL_FETCH_HAS_ERROR,
{{obj.NAME}}_EL_IS_LOADING, {{obj.NAME}}_EL_IS_LOADING,
{{obj.NAME}}_EL_FETCH_DATA_SUCCESS, {{obj.NAME}}_EL_FETCH_DATA_SUCCESS,
{% if not obj.read_only %} {% if not obj.read_only %}
{{obj.NAME}}_EL_IS_SAVING, {{obj.NAME}}_EL_IS_SAVING,
{{obj.NAME}}_EL_SAVING_HAS_ERROR,
{{obj.NAME}}_EL_SAVING_DATA_SUCCESS, {{obj.NAME}}_EL_SAVING_DATA_SUCCESS,
{% endif %} {% endif %}
...@@ -25,10 +26,13 @@ import { ...@@ -25,10 +26,13 @@ import {
} from "./action-types"; } from "./action-types";
{% for obj in data %} {% for obj in data %}
export function {{obj.name}}HasError(state = false, action) { export function {{obj.name}}FetchHasError(state = {status: false, error: null}, action) {
switch (action.type) { switch (action.type) {
case {{obj.NAME}}_HAS_ERROR: case {{obj.NAME}}_FETCH_HAS_ERROR:
return action.hasError; return {
status: action.hasError,
error: action.error
}
default: default:
return state; return state;
...@@ -80,11 +84,13 @@ export function {{obj.name}}Fetched(state = { data: Object(), fetchedAt: null }, ...@@ -80,11 +84,13 @@ export function {{obj.name}}Fetched(state = { data: Object(), fetchedAt: null },
export function {{obj.name}}ElHasError(state = false, action) { export function {{obj.name}}ElFetchHasError(state = {status: false, error: null}, action) {
switch (action.type) { switch (action.type) {
case {{obj.NAME}}_EL_HAS_ERROR: case {{obj.NAME}}_EL_FETCH_HAS_ERROR:
return action.hasError; return {
status: action.hasError,
error: action.error
}
default: default:
return state; return state;
} }
...@@ -121,25 +127,27 @@ export function {{obj.name}}ElFetched(state = { data: Object(), fetchedAt: null ...@@ -121,25 +127,27 @@ export function {{obj.name}}ElFetched(state = { data: Object(), fetchedAt: null
export function {{obj.name}}ElIsSaving(state = false, action) { export function {{obj.name}}ElIsSaving(state = false, action) {
switch (action.type) { switch (action.type) {
case {{obj.NAME}}_EL_IS_SAVING: case {{obj.NAME}}_EL_IS_SAVING:
return action.isPosting; return action.isSaving;
default: default:
return state; return state;
} }
} }
export function {{obj.name}}ElSaved(state = { data: Object(), savedAt: null }, action) {
export function {{obj.name}}ElSavingHasError(state = {status: false, error: null}, action) {
switch (action.type) { switch (action.type) {
case {{obj.NAME}}_EL_SAVING_DATA_SUCCESS: case {{obj.NAME}}_EL_SAVING_HAS_ERROR:
return { return {
data: action.{{obj.name}}El, status: action.hasError,
fetchedAt: action.{{obj.name}}ElSavedAt error: action.error
} }
default: default:
return state; return state;
} }
} }
{% endif %} {% endif %}
{% endfor %} {% endfor %}
\ No newline at end of file
...@@ -28,6 +28,9 @@ import { ...@@ -28,6 +28,9 @@ import {
import { import {
countriesFetchData, countriesFetchData,
currenciesFetchData, currenciesFetchData,
userDataElFetchData,
userDataElSaveData,
userDataElFetchHasError,
} from '../generated/actions'; } from '../generated/actions';
...@@ -107,6 +110,24 @@ class App extends MyComponent { ...@@ -107,6 +110,24 @@ class App extends MyComponent {
state = { state = {
open: true, open: true,
}; };
myComponentDidUpdate() {
// load the correct user data
if (this.props.userDataEl.isLoading) {
return false;
}
const userData = this.getFetchedData("userDataEl");
if (userData instanceof Array) {
if (userData.length == 0) {
if (!this.props.userDataEl.isSaving) {
this.props.createUserData();
}
} else if (userData.length == 1) {
this.props.fetchUserDataSingle(userData[0].id)
} else {
throw Error("We shouldn't have more thant one here !")
}
}
}
handleDrawerOpen = () => { handleDrawerOpen = () => {
this.setState({ open: true }); this.setState({ open: true });
...@@ -178,16 +199,20 @@ App.propTypes = { ...@@ -178,16 +199,20 @@ App.propTypes = {
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
return { return {
countries: state.countries, countries: state.countries,
currencies: state.currencies currencies: state.currencies,
userDataEl: state.userDataEl
} }
}; };
const mapDispatchToProps = (dispatch) => { const mapDispatchToProps = (dispatch) => {
return { return {
fetchUserDataSingle: (id) => dispatch(userDataElFetchData(id)),
fetchData: { fetchData: {
countries: () => dispatch(countriesFetchData()), countries: () => dispatch(countriesFetchData()),
currencies: () => dispatch(currenciesFetchData()), currencies: () => dispatch(currenciesFetchData()),
} userDataEl: () => dispatch(userDataElFetchData("")),
},
createUserData: () => dispatch(userDataElSaveData(Object()))
}; };
}; };
......
...@@ -2,90 +2,110 @@ import React, { Component } from 'react'; ...@@ -2,90 +2,110 @@ import React, { Component } from 'react';
import Loading from './other/Loading'; import Loading from './other/Loading';
class MyComponent extends Component { class MyComponent extends Component {
customErrorHandlers = {}
getFetchedData(prop) {
return this.props[prop].fetched.data; getFetchedData(prop) {
} return this.props[prop].fetched.data;
}
getAllFetchedData() {
let out = Object() getAllFetchedData() {
for (let prop_key in this.props) { let out = Object()
let prop = this.props[prop_key]; for (let prop_key in this.props) {
if (prop && 'fetched' in prop) { let prop = this.props[prop_key];
out[prop_key] = prop.fetched.data; if (prop && 'fetched' in prop) {
} out[prop_key] = prop.fetched.data;
} }
return out;
} }
return out;
joinCampus(campus) { }
const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety joinCampus(campus) {
res.university = universities[campus.university]; const { universities, countries, cities } = this.getAllFetchedData();
res.city = cities[campus.city] let res = Object.assign({}, campus); //copy for safety
res.country = countries[res.city.country] res.university = universities[campus.university];
return res; res.city = cities[campus.city]
res.country = countries[res.city.country]
return res;
}
checkProps(val) {
for (let el in this.props) {
let prop = this.props[el];
if (prop && val in prop && prop[val]) {
return true;
} }
}
checkProps(val) { return false;
for (let el in this.props) { }
let prop = this.props[el];