Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Julien Jerphanion
Rex Dri
Commits
02af4292
Commit
02af4292
authored
Aug 28, 2018
by
Florent Chehab
Browse files
Smarter generation
parent
4c296c75
Changes
6
Hide whitespace changes
Inline
Side-by-side
frontend/generate/generate_frontend_files.py
View file @
02af4292
...
@@ -40,13 +40,14 @@ API_BASE = "http://127.0.0.1:8000/api/"
...
@@ -40,13 +40,14 @@ API_BASE = "http://127.0.0.1:8000/api/"
contexts
=
[
contexts
=
[
{
{
'name'
:
'universities'
,
'name'
:
'universities'
,
'api_url'
:
API_BASE
+
"university/"
'api_url'
:
API_BASE
+
"university/"
,
},
{
},
{
'name'
:
'countries'
,
'name'
:
'countries'
,
'api_url'
:
API_BASE
+
"country/"
'api_url'
:
API_BASE
+
"country/"
},
{
},
{
'name'
:
'mainCampus'
,
'name'
:
'mainCampus'
,
'api_url'
:
API_BASE
+
"main_campus/"
'api_url'
:
API_BASE
+
"main_campus/"
,
'read_only'
:
True
}
}
]
]
...
...
frontend/generate/templates/action-types.tpl
View file @
02af4292
...
@@ -6,6 +6,10 @@
...
@@ -6,6 +6,10 @@
{% for obj in data %}
{% for obj in data %}
////////////////
// {
{
obj
.
NAME
}
}
////////////////
export const {
{
obj
.
NAME
}
}_HAS_ERROR = '{
{
obj
.
NAME
}
}_HAS_ERROR';
export const {
{
obj
.
NAME
}
}_HAS_ERROR = '{
{
obj
.
NAME
}
}_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';
...
@@ -13,7 +17,12 @@ export const {{obj.NAME}}_INVALIDATED = '{{obj.NAME}}_INVALIDATED';
...
@@ -13,7 +17,12 @@ export const {{obj.NAME}}_INVALIDATED = '{{obj.NAME}}_INVALIDATED';
export const {
{
obj
.
NAME
}
}_EL_HAS_ERROR = '{
{
obj
.
NAME
}
}_HAS_ERROR';
export const {
{
obj
.
NAME
}
}_EL_HAS_ERROR = '{
{
obj
.
NAME
}
}_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_FETCH_DATA_SUCCESS = '{
{
obj
.
NAME
}
}_FETCH_DATA_SUCCESS';
{% if 'read_only' not in obj or not obj.read_only %}
export const {
{
obj
.
NAME
}
}_EL_IS_SAVING = '{
{
obj
.
NAME
}
}_IS_POSTING';
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_SAVING_DATA_SUCCESS = '{
{
obj
.
NAME
}
}_POST_DATA_SUCCESS';
{% endif %}
{% endfor %}
{% endfor %}
frontend/generate/templates/actions.tpl
View file @
02af4292
...
@@ -15,15 +15,86 @@ import {
...
@@ -15,15 +15,86 @@ import {
{
{
obj
.
NAME
}
}_EL_INVALIDATED,
{
{
obj
.
NAME
}
}_EL_INVALIDATED,
{
{
obj
.
NAME
}
}_EL_HAS_ERROR,
{
{
obj
.
NAME
}
}_EL_HAS_ERROR,
{
{
obj
.
NAME
}
}_EL_IS_LOADING,
{
{
obj
.
NAME
}
}_EL_FETCH_DATA_SUCCESS,
{% if 'read_only' not in obj or not obj.read_only %}
{
{
obj
.
NAME
}
}_EL_IS_SAVING,
{
{
obj
.
NAME
}
}_EL_IS_SAVING,
{
{
obj
.
NAME
}
}_EL_SAVING_DATA_SUCCESS,
{
{
obj
.
NAME
}
}_EL_SAVING_DATA_SUCCESS,
{
{
obj
.
NAME
}
}_EL_IS_PUTTING,
{% endif %}
{
{
obj
.
NAME
}
}_EL_PUT_DATA_SUCCESS,
{% endfor %}
{% endfor %}
} from "./action-types";
} from "./action-types";
//////////////////////////////////
// generic function definitions
function _FetchData(pk, api_url, _IsLoading, _FetchDataSuccess, _Invalidated, _HasError, pk_required=false) {
if (pk_required
&&
pk == ""){
throw "pk shouldn't be empty when requesting a specific element";
}
return (dispatch) => {
dispatch(_IsLoading(true));
fetch(api_url)
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
dispatch(_IsLoading(false));
return response;
})
.then((response) => response.json())
.then((obj) => {
dispatch(_Invalidated(false));
dispatch(_FetchDataSuccess(obj));
})
.catch(() => dispatch(_HasError(true)));
};
}
function _ElSaveData(data, api_url, _IsLoading, _FetchDataSuccess, _Invalidated, _HasError) {
return (dispatch) => {
let method = "POST";
let pk = "";
if ('id' in data){
method = "PUT";
pk = data.id;
}
dispatch(_ElIsSaving(true));
let token = Cookies.get('csrftoken');
fetch(api_url+pk, {
method: method,
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': token
},
body: JSON.stringify(data)
})
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
dispatch(_ElIsSaving(false));
return response;
})
.then((response) => response.json())
.then((_El) => {
dispatch(_ElInvalidated(false));
dispatch(_ElSaveDataSuccess(_El));
})
.catch(() => dispatch(_ElHasError(true)));
};
}
/////////////////////////////////
{% for obj in data %}
{% for obj in data %}
export function {
{
obj
.
name
}
}HasError(bool) {
export function {
{
obj
.
name
}
}HasError(bool) {
return {
return {
...
@@ -57,27 +128,15 @@ export function {{obj.name}}FetchDataSuccess({{obj.name}}) {
...
@@ -57,27 +128,15 @@ export function {{obj.name}}FetchDataSuccess({{obj.name}}) {
}
}
export function {
{
obj
.
name
}
}FetchData(pk="") {
export function {
{
obj
.
name
}
}FetchData() {
return (dispatch) => {
return _FetchData(
dispatch({
{
obj
.
name
}
}IsLoading(true));
"",
"{
{
obj
.
api_url
}
}",
fetch("{
{
obj
.
api_url
}
}"+pk)
{
{
obj
.
name
}
}IsLoading,
.then((response) => {
{
{
obj
.
name
}
}FetchDataSuccess,
if (!response.ok) {
{
{
obj
.
name
}
}Invalidated,
throw Error(response.statusText);
{
{
obj
.
name
}
}HasError
}
)
dispatch({
{
obj
.
name
}
}IsLoading(false));
return response;
})
.then((response) => response.json())
.then(({
{
obj
.
name
}
}) => {
dispatch({
{
obj
.
name
}
}Invalidated(false));
dispatch({
{
obj
.
name
}
}FetchDataSuccess({
{
obj
.
name
}
}));
})
.catch(() => dispatch({
{
obj
.
name
}
}HasError(true)));
};
}
}
...
@@ -95,93 +154,61 @@ export function {{obj.name}}ElInvalidated(bool) {
...
@@ -95,93 +154,61 @@ export function {{obj.name}}ElInvalidated(bool) {
};
};
}
}
export function {
{
obj
.
name
}
}ElIsLoading(bool) {
export function {
{
obj
.
name
}
}ElIsSaving(bool) {
return {
return {
type: {
{
obj
.
NAME
}
}_EL_IS_
SAV
ING,
type: {
{
obj
.
NAME
}
}_EL_IS_
LOAD
ING,
is
Sav
ing: bool
is
Load
ing: bool
};
};
}
}
export function {
{
obj
.
name
}
}El
Save
DataSuccess({
{
obj
.
name
}
}El) {
export function {
{
obj
.
name
}
}El
Fetch
DataSuccess({
{
obj
.
name
}
}El) {
{
{
obj
.
name
}
}ElInvalidated(false)
{
{
obj
.
name
}
}ElInvalidated(false)
return {
return {
type: {
{
obj
.
NAME
}
}_EL_
SAVING
_DATA_SUCCESS,
type: {
{
obj
.
NAME
}
}_EL_
FETCH
_DATA_SUCCESS,
{
{
obj
.
name
}
}El,
{
{
obj
.
name
}
}El,
{
{
obj
.
name
}
}El
Sav
edAt: Date.now()
{
{
obj
.
name
}
}El
Fetch
edAt: Date.now()
};
};
}
}
export function {
{
obj
.
name
}
}ElPostData(data) {
export function {
{
obj
.
name
}
}ElFetchData(pk) {
return (dispatch) => {
return _FetchData(
dispatch({
{
obj
.
name
}
}ElIsSaving(true));
pk,
"{
{
obj
.
api_url
}
}",
{
{
obj
.
name
}
}ElIsLoading,
{
{
obj
.
name
}
}ElFetchDataSuccess,
{
{
obj
.
name
}
}ElInvalidated,
{
{
obj
.
name
}
}ElHasError,
true
)
}
let token = Cookies.get('csrftoken');
fetch("{
{
obj
.
api_url
}
}", {
{% if 'read_only' not in obj or not obj.read_only %}
method: 'POST',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': token
},
body: JSON.stringify(data)
})
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
dispatch({
{
obj
.
name
}
}ElIsSaving(false));
export function {
{
obj
.
name
}
}ElIsSaving(bool) {
return response;
return {
})
type: {
{
obj
.
NAME
}
}_EL_IS_SAVING,
.then((response) => response.json())
isSaving: bool
.then(({
{
obj
.
name
}
}El) => {
dispatch({
{
obj
.
name
}
}ElInvalidated(false));
dispatch({
{
obj
.
name
}
}ElSaveDataSuccess({
{
obj
.
name
}
}El));
})
.catch(() => dispatch({
{
obj
.
name
}
}ElHasError(true)));
};
};
}
}
export function {
{
obj
.
name
}
}ElSaveDataSuccess({
{
obj
.
name
}
}El) {
{
{
obj
.
name
}
}ElInvalidated(false)
return {
export function {
{
obj
.
name
}
}ElPutData(data) {
type: {
{
obj
.
NAME
}
}_EL_SAVING_DATA_SUCCESS,
return (dispatch) => {
{
{
obj
.
name
}
}El,
dispatch({
{
obj
.
name
}
}ElIsSaving(true));
{
{
obj
.
name
}
}ElSavedAt: Date.now()
let token = Cookies.get('csrftoken');
fetch("{
{
obj
.
api_url
}
}", {
method: 'PUT',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': token
},
body: JSON.stringify(data)
})
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
dispatch({
{
obj
.
name
}
}ElIsSaving(false));
return response;
})
.then((response) => response.json())
.then(({
{
obj
.
name
}
}El) => {
dispatch({
{
obj
.
name
}
}ElInvalidated(false));
dispatch({
{
obj
.
name
}
}ElSaveDataSuccess({
{
obj
.
name
}
}El));
})
.catch(() => dispatch({
{
obj
.
name
}
}ElHasError(true)));
};
};
}
}
export function {
{
obj
.
name
}
}ElSaveData(data) {
return _ElSaveData(data, "{
{
obj
.
api_url
}
}", {
{
obj
.
name
}
}ElIsLoading, {
{
obj
.
name
}
}ElFetchDataSuccess, {
{
obj
.
name
}
}ElInvalidated, {
{
obj
.
name
}
}ElHasError)
}
{% endif %}
{% endfor %}
{% endfor %}
\ No newline at end of file
frontend/generate/templates/combinedReducers.tpl
View file @
02af4292
...
@@ -8,15 +8,20 @@ import { combineReducers } from 'redux';
...
@@ -8,15 +8,20 @@ import { combineReducers } from 'redux';
import {
import {
{% for obj in data %}
{% for obj in data %}
{
{
obj
.
name
}
}
Fetch
ed,
{
{
obj
.
name
}
}
Invalidat
ed,
{
{
obj
.
name
}
}HasError,
{
{
obj
.
name
}
}HasError,
{
{
obj
.
name
}
}IsLoading,
{
{
obj
.
name
}
}IsLoading,
{
{
obj
.
name
}
}
Invalidat
ed,
{
{
obj
.
name
}
}
Fetch
ed,
{
{
obj
.
name
}
}ElHasError,
{
{
obj
.
name
}
}ElInvalidated,
{
{
obj
.
name
}
}ElInvalidated,
{
{
obj
.
name
}
}ElHasError,
{
{
obj
.
name
}
}ElIsLoading,
{
{
obj
.
name
}
}ElFetched,
{% if 'read_only' not in obj or not obj.read_only %}
{
{
obj
.
name
}
}ElIsSaving,
{
{
obj
.
name
}
}ElIsSaving,
{
{
obj
.
name
}
}ElSaved,
{
{
obj
.
name
}
}ElSaved,
{% endif %}
{% endfor %}
{% endfor %}
} from './reducers';
} from './reducers';
...
@@ -27,10 +32,22 @@ export const {{obj.name}}Reducers = combineReducers({
...
@@ -27,10 +32,22 @@ export const {{obj.name}}Reducers = combineReducers({
hasError: {
{
obj
.
name
}
}HasError,
hasError: {
{
obj
.
name
}
}HasError,
isLoading: {
{
obj
.
name
}
}IsLoading,
isLoading: {
{
obj
.
name
}
}IsLoading,
fetched: {
{
obj
.
name
}
}Fetched,
fetched: {
{
obj
.
name
}
}Fetched,
})
export const {
{
obj
.
name
}
}ElReducers = combineReducers({
invalidated: {
{
obj
.
name
}
}ElInvalidated,
hasError: {
{
obj
.
name
}
}ElHasError,
isLoading: {
{
obj
.
name
}
}ElIsLoading,
fetched: {
{
obj
.
name
}
}ElFetched,
{% if 'read_only' not in obj or not obj.read_only %}
isSaving: {
{
obj
.
name
}
}ElIsSaving,
isSaved: {
{
obj
.
name
}
}ElSaved,
{% endif %}
elInvalidated: {
{
obj
.
name
}
}ElInvalidated,
elHasError: {
{
obj
.
name
}
}ElHasError,
elIsPosting: {
{
obj
.
name
}
}ElIsSaving,
elSaved: {
{
obj
.
name
}
}ElSaved,
})
})
{% endfor %}
{% endfor %}
frontend/generate/templates/reducers.tpl
View file @
02af4292
...
@@ -6,17 +6,20 @@
...
@@ -6,17 +6,20 @@
import {
import {
{% for obj in data %}
{% for obj in data %}
{
{
obj
.
NAME
}
}_INVALIDATED,
{
{
obj
.
NAME
}
}_HAS_ERROR,
{
{
obj
.
NAME
}
}_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
}
}_EL_INVALIDATED,
{
{
obj
.
NAME
}
}_EL_INVALIDATED,
{
{
obj
.
NAME
}
}_EL_HAS_ERROR,
{
{
obj
.
NAME
}
}_EL_HAS_ERROR,
{
{
obj
.
NAME
}
}_EL_IS_LOADING,
{
{
obj
.
NAME
}
}_EL_FETCH_DATA_SUCCESS,
{% if 'read_only' not in obj or not obj.read_only %}
{
{
obj
.
NAME
}
}_EL_IS_SAVING,
{
{
obj
.
NAME
}
}_EL_IS_SAVING,
{
{
obj
.
NAME
}
}_EL_SAVING_DATA_SUCCESS,
{
{
obj
.
NAME
}
}_EL_SAVING_DATA_SUCCESS,
{
{
obj
.
NAME
}
}_EL_IS_PUTTING,
{% endif %}
{
{
obj
.
NAME
}
}_EL_PUT_DATA_SUCCESS,
{% endfor %}
{% endfor %}
} from "./action-types";
} from "./action-types";
...
@@ -52,6 +55,16 @@ export function {{obj.name}}Invalidated(state = false, action) {
...
@@ -52,6 +55,16 @@ export function {{obj.name}}Invalidated(state = false, action) {
}
}
}
}
export function {
{
obj
.
name
}
}ElIsLoading(state = false, action) {
switch (action.type) {
case {
{
obj
.
NAME
}
}_EL_IS_LOADING:
return action.isLoading;
default:
return state;
}
}
export function {
{
obj
.
name
}
}Fetched(state = { {
{
obj
.
name
}
}: [], {
{
obj
.
name
}
}FetchedAt: null }, action) {
export function {
{
obj
.
name
}
}Fetched(state = { {
{
obj
.
name
}
}: [], {
{
obj
.
name
}
}FetchedAt: null }, action) {
switch (action.type) {
switch (action.type) {
case {
{
obj
.
NAME
}
}_FETCH_DATA_SUCCESS:
case {
{
obj
.
NAME
}
}_FETCH_DATA_SUCCESS:
...
@@ -66,11 +79,10 @@ export function {{obj.name}}Fetched(state = { {{obj.name}}: [], {{obj.name}}Fetc
...
@@ -66,11 +79,10 @@ export function {{obj.name}}Fetched(state = { {{obj.name}}: [], {{obj.name}}Fetc
}
}
// Handling POST and PUT
export function {
{
obj
.
name
}
}ElHasError(state = false, action) {
export function {
{
obj
.
name
}
}ElHasError(state = false, action) {
switch (action.type) {
switch (action.type) {
case {
{
obj
.
NAME
}
}_E
l
_HAS_ERROR:
case {
{
obj
.
NAME
}
}_E
L
_HAS_ERROR:
return action.hasError;
return action.hasError;
default:
default:
...
@@ -88,6 +100,24 @@ export function {{obj.name}}ElInvalidated(state = false, action) {
...
@@ -88,6 +100,24 @@ export function {{obj.name}}ElInvalidated(state = false, action) {
}
}
}
}
export function {
{
obj
.
name
}
}ElFetched(state = { {
{
obj
.
name
}
}El: [], {
{
obj
.
name
}
}ElFetchedAt: null }, action) {
switch (action.type) {
case {
{
obj
.
NAME
}
}_EL_FETCH_DATA_SUCCESS:
return {
{
{
obj
.
name
}
}El: action.{
{
obj
.
name
}
}El,
fetchedAt: action.{
{
obj
.
name
}
}ElFetchedAt
}
default:
return state;
}
}
{% if 'read_only' not in obj or not obj.read_only %}
// Handling POST and PUT
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:
...
@@ -110,5 +140,6 @@ export function {{obj.name}}ElSaved(state = { {{obj.name}}El: [], {{obj.name}}El
...
@@ -110,5 +140,6 @@ export function {{obj.name}}ElSaved(state = { {{obj.name}}El: [], {{obj.name}}El
return state;
return state;
}
}
}
}
{% endif %}
{% endfor %}
{% endfor %}
\ No newline at end of file
frontend/src/reducers/index.js
View file @
02af4292
...
@@ -3,7 +3,9 @@ import { combineReducers } from 'redux';
...
@@ -3,7 +3,9 @@ import { combineReducers } from 'redux';
import
{
import
{
universitiesReducers
,
universitiesReducers
,
mainCampusReducers
,
mainCampusReducers
,
countriesReducers
countriesReducers
,
countriesElReducers
,
universitiesElReducers
}
from
'
../generated/combinedReducers
'
;
}
from
'
../generated/combinedReducers
'
;
import
{
import
{
...
@@ -15,9 +17,11 @@ const appReducers = combineReducers({
...
@@ -15,9 +17,11 @@ const appReducers = combineReducers({
})
})
const
rootReducer
=
combineReducers
({
const
rootReducer
=
combineReducers
({
countries
:
countriesReducers
,
countriesEl
:
countriesElReducers
,
universities
:
universitiesReducers
,
universities
:
universitiesReducers
,
universitiesEl
:
universitiesElReducers
,
mainCampus
:
mainCampusReducers
,
mainCampus
:
mainCampusReducers
,
countries
:
countriesReducers
,
app
:
appReducers
app
:
appReducers
})
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment