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

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):
owner = serializers.CharField(read_only=True)
def my_pre_save(self):
user = self.get_user_in_request()
self.override_validated_data({'owner': user})
self.override_validated_data({'owner': self.user})
# we try to recover the correct instance
query = UserData.objects.filter(owner=user)
query = UserData.objects.filter(owner=self.user)
if len(query) == 1:
self.instance = query[0]
......@@ -39,6 +38,7 @@ class UserDataSerializer(MyModelSerializer):
class UserDataViewSet(MyModelViewSet):
permission_classes = get_viewset_permissions("UserDataViewSet")
serializer_class = UserDataSerializer
BYPASS_DICT_MODE = True
def get_queryset(self):
return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101
......@@ -10,19 +10,19 @@
// {{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}}_FETCH_DATA_SUCCESS = '{{obj.NAME}}_FETCH_DATA_SUCCESS';
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_IS_LOADING = '{{obj.NAME}}_IS_LOADING';
export const {{obj.NAME}}_EL_FETCH_DATA_SUCCESS = '{{obj.NAME}}_FETCH_DATA_SUCCESS';
export const {{obj.NAME}}_EL_IS_LOADING = '{{obj.NAME}}_EL_IS_LOADING';
export const {{obj.NAME}}_EL_FETCH_DATA_SUCCESS = '{{obj.NAME}}_EL_FETCH_DATA_SUCCESS';
{% if not obj.read_only %}
export const {{obj.NAME}}_EL_IS_SAVING = '{{obj.NAME}}_IS_POSTING';
export const {{obj.NAME}}_EL_SAVING_DATA_SUCCESS = '{{obj.NAME}}_POST_DATA_SUCCESS';
export const {{obj.NAME}}_EL_IS_SAVING = '{{obj.NAME}}_EL_IS_SAVING';
export const {{obj.NAME}}_EL_SAVING_HAS_ERROR = '{{obj.NAME}}_EL_SAVING_HAS_ERROR';
{% endif %}
{% endfor %}
......@@ -8,18 +8,19 @@ import Cookies from 'js-cookie';
import {
{% for obj in data %}
{{obj.NAME}}_HAS_ERROR,
{{obj.NAME}}_FETCH_HAS_ERROR,
{{obj.NAME}}_IS_LOADING,
{{obj.NAME}}_FETCH_DATA_SUCCESS,
{{obj.NAME}}_INVALIDATED,
{{obj.NAME}}_EL_INVALIDATED,
{{obj.NAME}}_EL_HAS_ERROR,
{{obj.NAME}}_EL_FETCH_HAS_ERROR,
{{obj.NAME}}_EL_IS_LOADING,
{{obj.NAME}}_EL_FETCH_DATA_SUCCESS,
{% if not obj.read_only %}
{{obj.NAME}}_EL_IS_SAVING,
{{obj.NAME}}_EL_SAVING_HAS_ERROR,
{{obj.NAME}}_EL_SAVING_DATA_SUCCESS,
{% endif %}
......@@ -30,9 +31,12 @@ import {
// generic function definitions
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";
}
if (pk != ""){
api_end_point += pk;
}
return (dispatch) => {
dispatch(_IsLoading(true));
let token = Cookies.get('csrftoken');
......@@ -49,13 +53,16 @@ function _FetchData(pk, api_end_point, _IsLoading, _FetchDataSuccess, _Invalidat
dispatch(_FetchDataSuccess(obj));
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) => {
let method = "POST";
let pk = "";
......@@ -86,20 +93,24 @@ function _ElSaveData(data, api_end_point, _IsLoading, _FetchDataSuccess, _Invali
.then((response) => response.json())
.then((_El) => {
dispatch(_ElInvalidated(false));
dispatch(_ElSaveDataSuccess(_El));
dispatch(_ElFetchDataSuccess(_El)); // we use the same here
dispatch(_ElIsSaving(false));
})
.catch(() => dispatch(_ElHasError(true)));
.catch((e) => {
dispatch(_ElHasError(true, e))
dispatch(_ElIsSaving(false));
});
};
}
/////////////////////////////////
{% for obj in data %}
export function {{obj.name}}HasError(bool) {
export function {{obj.name}}FetchHasError(bool, error=null) {
return {
type: {{obj.NAME}}_HAS_ERROR,
hasError: bool
type: {{obj.NAME}}_FETCH_HAS_ERROR,
hasError: bool,
error
};
}
......@@ -135,15 +146,16 @@ export function {{obj.name}}FetchData() {
{{obj.name}}IsLoading,
{{obj.name}}FetchDataSuccess,
{{obj.name}}Invalidated,
{{obj.name}}HasError
{{obj.name}}FetchHasError
)
}
export function {{obj.name}}ElHasError(bool) {
export function {{obj.name}}ElFetchHasError(bool, error) {
return {
type: {{obj.NAME}}_EL_HAS_ERROR,
hasError: bool
type: {{obj.NAME}}_EL_FETCH_HAS_ERROR,
hasError: bool,
error
};
}
......@@ -180,7 +192,7 @@ export function {{obj.name}}ElFetchData(pk) {
{{obj.name}}ElIsLoading,
{{obj.name}}ElFetchDataSuccess,
{{obj.name}}ElInvalidated,
{{obj.name}}ElHasError,
{{obj.name}}ElFetchHasError,
true
)
}
......@@ -195,19 +207,17 @@ export function {{obj.name}}ElIsSaving(bool) {
};
}
export function {{obj.name}}ElSaveDataSuccess({{obj.name}}El) {
{{obj.name}}ElInvalidated(false)
export function {{obj.name}}ElSavingHasError(bool, error=null) {
return {
type: {{obj.NAME}}_EL_SAVING_DATA_SUCCESS,
{{obj.name}}El,
{{obj.name}}ElSavedAt: Date.now()
type: {{obj.NAME}}_EL_SAVING_HAS_ERROR,
hasError: bool,
error
};
}
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 %}
......
......@@ -9,18 +9,18 @@ import { combineReducers } from 'redux';
import {
{% for obj in data %}
{{obj.name}}Invalidated,
{{obj.name}}HasError,
{{obj.name}}FetchHasError,
{{obj.name}}IsLoading,
{{obj.name}}Fetched,
{{obj.name}}ElInvalidated,
{{obj.name}}ElHasError,
{{obj.name}}ElFetchHasError,
{{obj.name}}ElIsLoading,
{{obj.name}}ElFetched,
{% if not obj.read_only %}
{{obj.name}}ElIsSaving,
{{obj.name}}ElSaved,
{{obj.name}}ElSavingHasError,
{% endif %}
{% endfor %}
......@@ -29,25 +29,21 @@ import {
{% for obj in data %}
export const {{obj.name}}Reducers = combineReducers({
invalidated: {{obj.name}}Invalidated,
hasError: {{obj.name}}HasError,
fetchHasError: {{obj.name}}FetchHasError,
isLoading: {{obj.name}}IsLoading,
fetched: {{obj.name}}Fetched,
})
export const {{obj.name}}ElReducers = combineReducers({
invalidated: {{obj.name}}ElInvalidated,
hasError: {{obj.name}}ElHasError,
fetchHasError: {{obj.name}}ElFetchHasError,
isLoading: {{obj.name}}ElIsLoading,
fetched: {{obj.name}}ElFetched,
{% if not obj.read_only %}
isSaving: {{obj.name}}ElIsSaving,
isSaved: {{obj.name}}ElSaved,
savingHasError: {{obj.name}}ElSavingHasError
{% endif %}
})
{% endfor %}
......@@ -7,17 +7,18 @@
import {
{% for obj in data %}
{{obj.NAME}}_INVALIDATED,
{{obj.NAME}}_HAS_ERROR,
{{obj.NAME}}_FETCH_HAS_ERROR,
{{obj.NAME}}_IS_LOADING,
{{obj.NAME}}_FETCH_DATA_SUCCESS,
{{obj.NAME}}_EL_INVALIDATED,
{{obj.NAME}}_EL_HAS_ERROR,
{{obj.NAME}}_EL_FETCH_HAS_ERROR,
{{obj.NAME}}_EL_IS_LOADING,
{{obj.NAME}}_EL_FETCH_DATA_SUCCESS,
{% if not obj.read_only %}
{{obj.NAME}}_EL_IS_SAVING,
{{obj.NAME}}_EL_SAVING_HAS_ERROR,
{{obj.NAME}}_EL_SAVING_DATA_SUCCESS,
{% endif %}
......@@ -25,10 +26,13 @@ import {
} from "./action-types";
{% 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) {
case {{obj.NAME}}_HAS_ERROR:
return action.hasError;
case {{obj.NAME}}_FETCH_HAS_ERROR:
return {
status: action.hasError,
error: action.error
}
default:
return state;
......@@ -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) {
case {{obj.NAME}}_EL_HAS_ERROR:
return action.hasError;
case {{obj.NAME}}_EL_FETCH_HAS_ERROR:
return {
status: action.hasError,
error: action.error
}
default:
return state;
}
......@@ -121,25 +127,27 @@ export function {{obj.name}}ElFetched(state = { data: Object(), fetchedAt: null
export function {{obj.name}}ElIsSaving(state = false, action) {
switch (action.type) {
case {{obj.NAME}}_EL_IS_SAVING:
return action.isPosting;
return action.isSaving;
default:
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) {
case {{obj.NAME}}_EL_SAVING_DATA_SUCCESS:
case {{obj.NAME}}_EL_SAVING_HAS_ERROR:
return {
data: action.{{obj.name}}El,
fetchedAt: action.{{obj.name}}ElSavedAt
status: action.hasError,
error: action.error
}
default:
return state;
}
}
{% endif %}
{% endfor %}
\ No newline at end of file
......@@ -28,6 +28,9 @@ import {
import {
countriesFetchData,
currenciesFetchData,
userDataElFetchData,
userDataElSaveData,
userDataElFetchHasError,
} from '../generated/actions';
......@@ -107,6 +110,24 @@ class App extends MyComponent {
state = {
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 = () => {
this.setState({ open: true });
......@@ -178,16 +199,20 @@ App.propTypes = {
const mapStateToProps = (state) => {
return {
countries: state.countries,
currencies: state.currencies
currencies: state.currencies,
userDataEl: state.userDataEl
}
};
const mapDispatchToProps = (dispatch) => {
return {
fetchUserDataSingle: (id) => dispatch(userDataElFetchData(id)),
fetchData: {
countries: () => dispatch(countriesFetchData()),
currencies: () => dispatch(currenciesFetchData()),
}
userDataEl: () => dispatch(userDataElFetchData("")),
},
createUserData: () => dispatch(userDataElSaveData(Object()))
};
};
......
......@@ -2,90 +2,110 @@ import React, { Component } from 'react';
import Loading from './other/Loading';
class MyComponent extends Component {
getFetchedData(prop) {
return this.props[prop].fetched.data;
}
getAllFetchedData() {
let out = Object()
for (let prop_key in this.props) {
let prop = this.props[prop_key];
if (prop && 'fetched' in prop) {
out[prop_key] = prop.fetched.data;
}
}
return out;
customErrorHandlers = {}
getFetchedData(prop) {
return this.props[prop].fetched.data;
}
getAllFetchedData() {
let out = Object()
for (let prop_key in this.props) {
let prop = this.props[prop_key];
if (prop && 'fetched' in prop) {
out[prop_key] = prop.fetched.data;
}
}
joinCampus(campus) {
const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety
res.university = universities[campus.university];
res.city = cities[campus.city]
res.country = countries[res.city.country]
return res;
return out;
}
joinCampus(campus) {
const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety
res.university = universities[campus.university];
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) {
for (let el in this.props) {
let prop = this.props[el];
if (prop && val in prop && prop[val]) {
return true;
}
}
return false;
}
checkPropsHasError() {
for (let prop_key in this.props) {
let prop = this.props[prop_key];
if (prop && 'fetchHasError' in prop) {
if (prop.fetchHasError.status) {
if (prop_key in this.customErrorHandlers){
console.log("icicicicici");
} else {
return true;
}
}
return false;
}
}
return false;
}
checkPropsHasError() {
return this.checkProps('hasError');
}
checkPropsIsLoading() {
return this.checkProps('isLoading');
}
checkPropsIsLoading() {
return this.checkProps('isLoading');
}
checkPropsInvalidated() {
return this.checkProps('invalidated');
}
checkPropsInvalidated() {
return this.checkProps('invalidated');
}
checkPropsIsSaving() {
return this.checkProps('isSaving');
}
loadPropsIfNeeded() {
for (let prop_key in this.props) {
let prop = this.props[prop_key];
if (prop && 'fetched' in prop) {
if ((!prop.fetched.fetchedAt) || prop.invalidated) {
if (!prop.isLoading) {
this.props.fetchData[prop_key]();
}
}
}
loadPropsIfNeeded() {
if (this.checkPropsHasError()){
return false;
}
for (let prop_key in this.props) {
let prop = this.props[prop_key];
if (prop && 'fetched' in prop) {
if ((!prop.fetched.fetchedAt) || prop.invalidated) {
if (!prop.isLoading) {
this.props.fetchData[prop_key]();
}
}
}
}
componentDidMount() {
this.loadPropsIfNeeded();
this.myComponentDidMount();
}
componentDidMount() {
this.loadPropsIfNeeded();
this.myComponentDidMount();
}
myComponentDidMount() { };
componentDidUpdate() {
// TODO ajouter expire date
this.loadPropsIfNeeded();
this.myComponentDidUpdate();
}
myComponentDidUpdate() { };
render() {
if (this.checkPropsHasError()) {
return <p>Sorry! There was an error loading the items</p>;
}
myComponentDidMount() { };
componentDidUpdate() {
// TODO ajouter expire date
this.loadPropsIfNeeded();
this.myComponentDidMount();
if (this.checkPropsIsLoading() || this.checkPropsInvalidated() || this.checkPropsIsSaving()) {
return <Loading />;
}
myComponentDidMount() { };
render() {
if (this.checkPropsHasError()) {
return <p>Sorry! There was an error loading the items</p>;
}
if (this.checkPropsIsLoading() || this.checkPropsInvalidated()) {
return <Loading />;
}
return this.myRender();
}
return this.myRender();
}
}
......
......@@ -10,7 +10,6 @@ import { BrowserRouter as Router, Route } from 'react-router-dom';
class ThemeProvider extends React.Component {
render() {
console.log("ici")
return (
<div>
<MuiThemeProvider theme={createMuiTheme(this.props.theme)}>
......
......@@ -18,7 +18,7 @@ class Settings extends MyComponent {
myRender() {
return (
<ColorTools style={{backgroundColor:"#eeeeee"}}></ColorTools>
<ColorTools/> //TODO fix backgroud
);
}
......
......@@ -8,6 +8,7 @@ import {
universitiesElReducers,
currenciesReducers,
citiesReducers,
userDataElReducers
} from '../generated/combinedReducers';
import { saveMainMapPosition } from './map';
......@@ -31,6 +32,7 @@ const rootReducer = combineReducers({
universitiesEl: universitiesElReducers,
currencies: currenciesReducers,
mainCampuses: mainCampusesReducers,
userDataEl: userDataElReducers,
app: appReducers
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment