Update Reducers + Update DB + tmp clean

This commit is contained in:
Vincent BRIDIER 2022-12-28 13:27:14 +01:00
parent 73da29371d
commit 56e98c5d5c
No known key found for this signature in database
GPG key ID: 8571BFA20420D512
35 changed files with 486 additions and 747 deletions

View file

@ -1,7 +1,21 @@
import 'react-native-gesture-handler';
// V2
import React from 'react';
import { createStore } from 'redux';
// Redux
import { Provider } from 'react-redux';
import { store } from './App/Store/ConfigureStore';
// i18n
import i18n from "./I18n";
// Controllers
import SyncController from './App/Controllers/SyncController';
// Views
import InstallScreen from './App/Views/InstallScreen';
import LoginScreen from './App/Views/LoginScreen';
// END V2
import SyncScreen from './App/Views/SyncScreen';
import HomeScreen from './App/Views/HomeScreen';
import 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { TouchableOpacity, View, Image, Text, TextInput, StyleSheet, Alert } from 'react-native';
@ -10,164 +24,24 @@ import Icon from 'react-native-vector-icons/FontAwesome5';
import FlashMessage, { showMessage } from 'react-native-flash-message';
import * as SplashScreen from 'expo-splash-screen';
import LoginScreen from './Views/Login';
import HomeScreen from './Views/Home';
import DirectoriesScreen from './Views/Directories';
import VideoScreen from './Views/Video';
import PDFScreen from './Views/PDF';
import SyncScreen from './Views/Sync';
import ContactScreen from './Views/Contact';
import ContactDetailsScreen from './Views/ContactDetails';
import OnlyVideosScreen from './Views/OnlyVideos';
import SearchScreen from "./Views/Search";
import MySpaceScreen from './Views/MySpace';
import UsersModel from './Models/Users';
import DirectoriesModel from './Models/Directories';
import DocumentsModel from './Models/Documents';
import ContactsModel from './Models/Contacts';
import SendBrochureModel from './Models/SendBrochure';
import CommonModel from './Models/Common';
import Sync from './Controllers/Sync';
import Helpers from "./Controllers/Helpers";
import i18n from "./I18n";
SplashScreen.preventAutoHideAsync();
const initialState = {
locale: 'fr',
users: {},
directories: {},
documents: {},
contacts: {},
syncVersion: 0,
logged: undefined,
currentUser: {},
currentOpenedDoc: {},
ShowIsActive: 0,
};
function reducer(state = initialState, action) {
//console.log('reducer', state, action);
//console.log('DISPATCH');
switch (action.type) {
case 'INIT':
let docs = DocumentsModel.getAll(DirectoriesModel.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
false,
state.locale
));
return {
...state,
users: UsersModel.getAll(),
directories: DirectoriesModel.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
true,
state.locale
),
documents: docs.filter(item => item.lang === state.locale),
contacts: ContactsModel.getByUser(state.currentUser.id),
ShowIsActive: CommonModel.get('ShowIsActive')['value'],
};
case 'INIT_USERS':
return {
...state,
users: UsersModel.getAll(),
};
case 'SET_CURRENT_USER':
return {
...state,
currentUser: JSON.parse(action.data),
};
case 'SET_LOGGED':
if (action.data === false) {
CommonModel.delete('isLogged');
}
return {
...state,
logged: action.data,
};
case 'UPDATE_LOCALE':
let nxt;
if (action.data === undefined) {
const availableLocales = ['fr', 'en', 'de'];
if (availableLocales.indexOf(i18n.locale) === availableLocales.length - 1) {
nxt = availableLocales[0];
} else {
nxt = availableLocales[availableLocales.indexOf(i18n.locale) + 1];
}
} else {
nxt = action.data;
}
i18n.locale = nxt;
CommonModel.update({ key: 'locale', value: nxt });
let docsL = DocumentsModel.getAll(DirectoriesModel.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
false,
nxt
));
return {
...state,
locale: nxt,
directories: DirectoriesModel.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
true,
nxt
),
documents: docsL.filter(item => item.lang === nxt),
};
case 'SET_CURRENT_OPENED_DOC':
return {
...state,
currentOpenedDoc: action.data
};
case 'UPDATE_VERSION':
return {
...state,
syncVersion: action.data,
};
case 'UPDATE_SHOW_IS_ACTIVE':
Sync.updateShowIsActive(action.data);
return {
...state,
ShowIsActive: action.data,
};
case 'UPDATE_CONTACT':
ContactsModel.update(action.data);
return {
...state,
contacts: ContactsModel.getByUser(state.currentUser.id),
};
case 'ADD_CONTACT':
ContactsModel.add(action.data);
return {
...state,
contacts: ContactsModel.getByUser(state.currentUser.id),
};
case 'DELETE_CONTACT':
ContactsModel.delete(action.data);
return {
...state,
contacts: ContactsModel.getByUser(state.currentUser.id),
};
case 'SEND_BROCHURE':
SendBrochureModel.add(action.data);
return state;
default:
return state;
}
}
const store = createStore(reducer);
const Stack = createNativeStackNavigator();
//SplashScreen.preventAutoHideAsync(); //Keep
// V2
store.dispatch({ type: 'INIT_APP' });
store.dispatch({ type: 'INIT_LOCALE' });
store.dispatch({ type: 'INIT_USERS' });
// END V2
const Stack = createNativeStackNavigator();
class App extends React.Component {
state = {
@ -178,29 +52,26 @@ class App extends React.Component {
};
componentDidMount(): void {
const unsubscribe = store.subscribe(this.handleChange.bind(this));
if (Sync.isInstalled() && Sync.isLogged()) {
store.dispatch({
type: 'SET_CURRENT_USER',
data: CommonModel.get('isLogged').value,
});
store.dispatch({ type: 'SET_LOGGED', data: true });
}
const savedLocale = CommonModel.get('locale');
if (savedLocale !== undefined && savedLocale !== false) {
store.dispatch({ type: 'UPDATE_LOCALE', data: savedLocale.value });
}
// if (Sync.isLogged()) {
// store.dispatch({
// type: 'SET_CURRENT_USER',
// data: CommonModel.get('isLogged').value,
// });
// store.dispatch({ type: 'SET_LOGGED', data: true });
// }
}
handleChange() {
const logged = store.getState().logged;
const logged = store.getState().app.logged;
if (logged === false) {
CommonModel.delete('isLogged');
}
if (logged !== undefined) {
this.setState({ logged: logged });
}
this.setState({ ShowIsActive: store.getState().ShowIsActive });
this.setState({ ShowIsActive: store.getState().app.ShowIsActive });
}
LogoTitle(title) {
@ -253,32 +124,31 @@ class App extends React.Component {
}
render() {
const savedLocale = CommonModel.get('locale');
let locale;
if (savedLocale !== undefined) {
locale = savedLocale.value;
} else {
locale = store.getState().locale;
}
let flag;
switch (locale) {
case "fr":
flag = require('./assets/img/flags/fr.png');
break;
case "en":
flag = require('./assets/img/flags/en.png');
break;
case "de":
flag = require('./assets/img/flags/de.png');
break;
case "es":
flag = require('./assets/img/flags/es.png');
break;
}
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator>
{store.getState().app.isSetup === false &&
<Stack.Screen
name="InstallScreen"
component={InstallScreen}
options={(navigation, route) => ({
headerTitle: () => this.LogoTitle(i18n.t('install.installation')),
headerRight: () => (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<TouchableOpacity
onPress={() => {
store.dispatch({ type: 'EDIT_LOCALE' });
this.setState({ state: this.state }); // to force re-rendering
}}
style={{ marginRight: 15 }}>
<Image source={this.renderFlag()} style={{ width: 25, height: 25 }} />
</TouchableOpacity>
</View>
),
})}
/>
}
{this.state.logged === false ? (
<Stack.Screen
name="LoginScreen"
@ -289,11 +159,11 @@ class App extends React.Component {
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<TouchableOpacity
onPress={() => {
store.dispatch({ type: 'UPDATE_LOCALE' });
store.dispatch({ type: 'EDIT_LOCALE' });
this.setState({ state: this.state }); // to force re-rendering
}}
style={{ marginRight: 15 }}>
<Image source={flag} style={{ width: 25, height: 25 }} />
<Image source={this.renderFlag()} style={{ width: 25, height: 25 }} />
</TouchableOpacity>
</View>
),
@ -323,10 +193,10 @@ class App extends React.Component {
</View>
<TouchableOpacity
onPress={() => {
store.dispatch({ type: 'UPDATE_LOCALE' });
store.dispatch({ type: 'EDIT_LOCALE' });
}}
style={{ marginRight: 25 }}>
<Image source={flag} style={{ width: 25, height: 25 }} />
<Image source={this.renderFlag()} style={{ width: 25, height: 25 }} />
</TouchableOpacity>
{this.state.ShowIsActive === '1' && (
<TouchableOpacity
@ -447,6 +317,26 @@ class App extends React.Component {
</Provider>
);
}
renderFlag() {
let flag;
switch (store.getState().locale.locale) {
case "fr":
flag = require('./assets/img/flags/fr.png');
break;
case "en":
flag = require('./assets/img/flags/en.png');
break;
case "de":
flag = require('./assets/img/flags/de.png');
break;
case "es":
flag = require('./assets/img/flags/es.png');
break;
}
return flag;
}
}
const styles = StyleSheet.create({

View file

@ -1,3 +1,29 @@
export const ContactsSchema = {
name: 'Contacts',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
type: 'string',
other: { type: 'string', optional: true },
select1: { type: 'string', optional: true },
select2: { type: 'string', optional: true },
name: 'string',
firstname: 'string',
company: { type: 'string', optional: true },
address: { type: 'string', optional: true },
phone: 'string',
products: { type: 'string', optional: true },
// TODO : card_url ?
notes: { type: 'string', optional: true },
visits: { type: 'string', optional: true },
user_id: 'int',
uniq_id: 'string',
to_delete: { type: 'bool', default: false },
synced: { type: 'bool', default: true },
},
};
class ContactModel {
constructor(realm) {
this.schema = 'Contacts';

View file

@ -1,3 +1,14 @@
export const DirectoriesSchema = {
name: 'Directories',
primaryKey: 'id',
properties: {
id: 'int',
name: 'string',
parent: { type: 'int', optional: true },
order: 'int',
needAuthorization: 'int',
},
};
class DirectoryModel {
constructor(realm) {
this.schema = 'Directories';

View file

@ -1,3 +1,18 @@
export const DocumentsSchema = {
name: 'Documents',
primaryKey: 'id',
properties: {
id: 'int',
uuid: 'string',
title: 'string',
type: 'string',
path: 'string',
directory: 'int',
lang: 'string',
updated_at: 'string',
},
};
class DocumentModel {
constructor(realm) {
this.schema = 'Documents';

View file

@ -1,3 +1,16 @@
export const SendBrochuresSchema = {
name: 'SendBrochures',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
subject: 'string',
message: 'string',
documents: 'string',
user_id: 'int'
},
};
class SendBrochureModel {
constructor(realm) {
this.schema = 'SendBrochures';

View file

@ -1,3 +1,13 @@
export const SettingsSchema = {
name: 'Settings',
primaryKey: 'id',
properties: {
id: 'int',
key: 'string',
value: 'string',
},
};
class SettingModel {
constructor(realm) {
this.schema = 'Settings';
@ -59,4 +69,4 @@ class SettingModel {
}
export default SettingModel;
export default SettingModel;

View file

@ -1,3 +1,17 @@
export const UsersSchema = {
name: 'Users',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
surname: 'string',
firstname: 'string',
password: 'string',
role: 'string',
authorizedFolders: 'string',
},
};
class UserModel {
constructor(realm) {
this.schema = 'Users';

View file

@ -0,0 +1,10 @@
// Locale
export const INIT_LOCALE = "INIT_LOCALE";
export const EDIT_LOCALE = "EDIT_LOCALE";
// Users
export const INIT_USERS = "INIT_USERS";
// Contacts
export const INIT_CONTACT = "INIT_CONTACT";
export const ADD_CONTACT = "ADD_CONTACT";
export const EDIT_CONTACT = "EDIT_CONTACT";
export const DELETE_CONTACT = "DELETE_CONTACT";

View file

@ -0,0 +1,47 @@
import { INIT_CONTACT, ADD_CONTACT, EDIT_CONTACT, DELETE_CONTACT } from "./actionType";
/**
* Init contact
* @param {object} data The contact data
*/
export const initContact = data => {
return {
type: INIT_CONTACT,
data,
};
};
/**
* Add contact
* @param {object} data The contact data
*/
export const addContact = data => {
return {
type: ADD_CONTACT,
data,
};
};
/**
* Edit contact
* @param {string} uid The contact uid
* @param {object} data The contact data
*/
export const editContact = (uid, data) => {
return {
type: EDIT_CONTACT,
uid,
data,
};
};
/**
* Delete contact
* @param {string} uid The contact uid
*/
export const deleteContact = uid => {
return {
type: DELETE_CONTACT,
uid,
};
};

View file

@ -0,0 +1,23 @@
import { INIT_LOCALE, EDIT_LOCALE } from "./actionType";
/**
* Init locale
* @param {object} data The locale data
*/
export const initLocale = data => {
return {
type: INIT_LOCALE,
data,
};
};
/**
* Edit locale
* @param {object} data The locale data
*/
export const editLocale = data => {
return {
type: EDIT_LOCALE,
data,
};
};

View file

@ -0,0 +1,12 @@
import { INIT_USERS } from "./actionType";
/**
* Init users
* @param {object} data The users data
*/
export const initUsers = data => {
return {
type: INIT_USERS,
data,
};
};

View file

@ -1,9 +1,15 @@
import { createStore, combineReducers } from "redux";
import appReducer from "./Reducers/AppReducer";
import localesReducer from "./Reducers/locales";
import usersReducer from "./Reducers/users";
import contactsReducer from "./Reducers/contacts";
const rootReducer = combineReducers({
app: appReducer
app: appReducer,
contacts: contactsReducer,
locale: localesReducer,
users: usersReducer
});
export const store = createStore(rootReducer);

View file

@ -1,15 +1,12 @@
import SyncController from "../../Controllers/SyncController";
// Database
import { Setting, Contact, User, Directory, Document, SendBrochure } from '../../../Database';
// Translations
import i18n from "../../../I18n";
import { Setting, Directory, Document, SendBrochure } from '../../../Database';
const initialState = {
isSetup: false,
locale: 'fr',
users: {},
directories: {},
documents: {},
contacts: {},
syncVersion: 0,
logged: undefined,
currentUser: {},
@ -18,7 +15,21 @@ const initialState = {
};
const reducer = (state = initialState, action) => {
let saved;
switch (action.type) {
case 'INIT_APP':
saved = Setting.get('isSetup');
return {
...state,
isSetup: saved === undefined ? false : saved.value === "true" ? true : false
};
case 'SET_ISSETUP':
Setting.upsert({ key: 'isSetup', value: "true" });
saved = Setting.get('isSetup');
return {
...state,
isSetup: saved === undefined ? false : saved.value === "true" ? true : false
};
case 'INIT':
let directories = Directory.getAll(
state.currentUser.role,
@ -27,9 +38,9 @@ const reducer = (state = initialState, action) => {
state.locale
);
let docs = Document.getAll(directories);
let ShowIsActive = Setting.get('ShowIsActive');
return {
...state,
users: User.getAll(),
directories: Directory.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
@ -37,13 +48,7 @@ const reducer = (state = initialState, action) => {
state.locale
),
documents: docs.filter(item => item.lang === state.locale),
contacts: Contact.getByUser(state.currentUser.id),
ShowIsActive: Setting.get('ShowIsActive')['value'],
};
case 'INIT_USERS':
return {
...state,
users: User.getAll(),
ShowIsActive: ShowIsActive === undefined ? false : ShowIsActive.value,
};
case 'SET_CURRENT_USER':
return {
@ -58,37 +63,37 @@ const reducer = (state = initialState, action) => {
...state,
logged: action.data,
};
case 'UPDATE_LOCALE':
let nxt;
if (action.data === undefined) {
const availableLocales = ['fr', 'en', 'de'];
if (availableLocales.indexOf(i18n.locale) === availableLocales.length - 1) {
nxt = availableLocales[0];
} else {
nxt = availableLocales[availableLocales.indexOf(i18n.locale) + 1];
}
} else {
nxt = action.data;
}
i18n.locale = nxt;
Setting.upsert({ key: 'locale', value: nxt });
let docsL = Document.getAll(Directory.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
false,
nxt
));
return {
...state,
locale: nxt,
directories: Directory.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
true,
nxt
),
documents: docsL.filter(item => item.lang === nxt),
};
// case 'UPDATE_LOCALE':
// let nxt;
// if (action.data === undefined) {
// const availableLocales = ['fr', 'en', 'de'];
// if (availableLocales.indexOf(i18n.locale) === availableLocales.length - 1) {
// nxt = availableLocales[0];
// } else {
// nxt = availableLocales[availableLocales.indexOf(i18n.locale) + 1];
// }
// } else {
// nxt = action.data;
// }
// i18n.locale = nxt;
// Setting.upsert({ key: 'locale', value: nxt });
// let docsL = Document.getAll(Directory.getAll(
// state.currentUser.role,
// state.currentUser.authorizedFolders,
// false,
// nxt
// ));
// return {
// ...state,
// locale: nxt,
// directories: Directory.getAll(
// state.currentUser.role,
// state.currentUser.authorizedFolders,
// true,
// nxt
// ),
// documents: docsL.filter(item => item.lang === nxt),
// };
case 'SET_CURRENT_OPENED_DOC':
return {
...state,
@ -105,24 +110,6 @@ const reducer = (state = initialState, action) => {
...state,
ShowIsActive: action.data,
};
case 'UPDATE_CONTACT':
Contact.update(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case 'ADD_CONTACT':
Contact.add(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case 'DELETE_CONTACT':
Contact.delete(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case 'SEND_BROCHURE':
SendBrochure.add(action.data);
return state;

View file

@ -0,0 +1,39 @@
import { INIT_CONTACT, ADD_CONTACT, EDIT_CONTACT, DELETE_CONTACT } from "../Actions/actionType";
// Models
import { Contact } from "../../../Database";
const initialState = [];
const reducer = (state = initialState, action) => {
switch (action.type) {
case INIT_CONTACT:
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case ADD_CONTACT:
Contact.add(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case EDIT_CONTACT:
Contact.update(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
case DELETE_CONTACT:
Contact.delete(action.data);
return {
...state,
contacts: Contact.getByUser(state.currentUser.id),
};
default: {
return state;
}
}
};
export default reducer;

View file

@ -0,0 +1,45 @@
import { INIT_LOCALE, EDIT_LOCALE } from "../Actions/actionType";
// Models
import { Setting } from "../../../Database";
// Translations
import i18n from "../../../I18n";
const initialState = [];
const reducer = (state = initialState, action) => {
switch (action.type) {
case INIT_LOCALE: {
const savedLocale = Setting.get('locale');
return {
...state,
locale: savedLocale === undefined ? 'fr' : savedLocale === false ? 'fr' : savedLocale.value
};
}
case EDIT_LOCALE: {
let nxt;
if (action.data === undefined) {
const availableLocales = ['fr', 'en', 'de'];
if (availableLocales.indexOf(i18n.locale) === availableLocales.length - 1) {
nxt = availableLocales[0];
} else {
nxt = availableLocales[availableLocales.indexOf(i18n.locale) + 1];
}
} else {
nxt = action.data;
}
i18n.locale = nxt;
Setting.upsert({ key: 'locale', value: nxt });
return {
...state,
locale: nxt,
};
}
default: {
return state;
}
}
};
export default reducer;

View file

@ -0,0 +1,22 @@
import { INIT_USERS } from "../Actions/actionType";
// Models
import { User } from "../../../Database";
const initialState = [];
const reducer = (state = initialState, action) => {
switch (action.type) {
case INIT_USERS: {
return {
...state,
users: User.getAll(),
};
}
default: {
return state;
}
}
};
export default reducer;

View file

@ -162,7 +162,7 @@ class ContactDetailsScreen extends React.Component {
};
if (action === 'edit') {
contact.id = this.state.tmpID;
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.populate();
showMessage({
message: i18n.t('contact_details_s.contact_saved') + '.',

View file

@ -115,7 +115,7 @@ class ContactScreen extends React.Component {
synced: false,
user_id: nextUser.id,
};
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.setState({ showTransferContact: false });
showMessage({
message: i18n.t('contact_s.contact_transferred') + '.',

View file

@ -14,7 +14,7 @@ import * as FileSystem from 'expo-file-system';
function mapStateToProps(state) {
return {
directories: state.app.directories,
locale: state.app.locale,
locale: state.locale.locale,
};
}

View file

@ -1,5 +1,7 @@
import React from 'react';
import { ImageBackground, View, Image, Text, TextInput, Button, Alert } from 'react-native';
// Redux
import { connect } from 'react-redux';
// Helpers
import Helpers from '../Lib/Helpers';
// Common Styles
@ -11,7 +13,14 @@ import i18n from "../../I18n";
// Controller
import InstallController from '../Controllers/InstallController';
import SyncController from '../Controllers/SyncController';
// Database
import { User } from '../../Database';
function mapStateToProps(state) {
return {
isSetup: state.app.isSetup
};
}
class InstallScreen extends React.Component {
state = {
processing: false,
@ -58,16 +67,33 @@ class InstallScreen extends React.Component {
);
}
install() {
async install() {
this.setState({ processing: true, txtStep: i18n.t("install.get_app_setting") });
if (InstallController.getConfig(this.state.url)) {
this.setState({ txtStep: i18n.t("install.get_content_setting") });
if (InstallController.getAppConfig(this.state.url)) {
this.props.navigation.navigate('SyncScreen', { forceSync: true });
// getUsers
this.setState({ txtStep: i18n.t('sync_s.updating_users') + '...' });
const resUsers = await SyncController.getUsers().then(res => {
User.clear();
return res.data;
}).catch(error => {
console.log(error);
Alert.alert(
i18n.t('error.error'),
i18n.t('error.error_has_occurred')
);
return
});
resUsers.forEach(user => {
User.add(user);
});
this.props.dispatch({ type: 'SET_ISSETUP' });
this.props.navigation.navigate('LoginScreen');
}
}
this.setState({ processing: false });
this.setState({ processing: false, txtStep: "" });
}
}
export default InstallScreen;
export default connect(mapStateToProps)(InstallScreen);

View file

@ -17,8 +17,8 @@ import SyncController from '../Controllers/SyncController';
function mapStateToProps(state) {
return {
users: state.app.users,
locale: state.app.locale,
users: state.users.users,
locale: state.locale.locale,
};
}

View file

@ -280,7 +280,6 @@ class SyncScreen extends React.Component {
}
finishSync(version) {
console.log('here')
this.props.dispatch({ type: 'INIT' });
SyncController.updateVersion(version);
this.setState({ txtStep: i18n.t('sync_s.update_completed') + '.', processing: false });

View file

@ -1,103 +1,29 @@
const CommonSchema = {
name: 'Common',
primaryKey: 'id',
properties: {
id: 'int',
key: 'string',
value: 'string',
},
};
import Realm from "realm";
const UserSchema = {
name: 'Users',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
surname: 'string',
firstname: 'string',
password: 'string',
role: 'string',
authorizedFolders: 'string',
},
};
const DirectoriesSchema = {
name: 'Directories',
primaryKey: 'id',
properties: {
id: 'int',
name: 'string',
parent: { type: 'int', optional: true },
order: 'int',
needAuthorization: 'int',
},
};
const DocumentsSchema = {
name: 'Documents',
primaryKey: 'id',
properties: {
id: 'int',
uuid: 'string',
title: 'string',
type: 'string',
path: 'string',
directory: 'int',
lang: 'string',
updated_at: 'string',
},
};
const ContactsSchema = {
name: 'Contacts',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
type: 'string',
other: { type: 'string', optional: true },
select1: { type: 'string', optional: true },
select2: { type: 'string', optional: true },
name: 'string',
firstname: 'string',
company: { type: 'string', optional: true },
address: { type: 'string', optional: true },
phone: 'string',
products: { type: 'string', optional: true },
// TODO : card_url ?
notes: { type: 'string', optional: true },
visits: { type: 'string', optional: true },
user_id: 'int',
uniq_id: 'string',
to_delete: { type: 'bool', default: false },
synced: { type: 'bool', default: true },
},
};
const SendBrochureSchema = {
name: 'SendBrochure',
primaryKey: 'id',
properties: {
id: 'int',
email: 'string',
subject: 'string',
message: 'string',
documents: 'string',
user_id: 'int'
},
};
import ContactModel, { ContactsSchema } from "./App/Models/Contact";
import DirectoryModel, { DirectoriesSchema } from "./App/Models/Directory";
import DocumentModel, { DocumentsSchema } from "./App/Models/Document";
import SendBrochureModel, { SendBrochuresSchema } from "./App/Models/SendBrochure";
import SettingModel, { SettingsSchema } from "./App/Models/Setting";
import UserModel, { UsersSchema } from "./App/Models/User";
const Database = {
schema: [
CommonSchema,
UserSchema,
ContactsSchema,
DirectoriesSchema,
DocumentsSchema,
ContactsSchema,
SendBrochureSchema,
SendBrochuresSchema,
SettingsSchema,
UsersSchema
],
encryptionKey: new Int8Array(64)
//encryptionKey: new Int8Array(64)
};
export default Database;
let realm = new Realm(Database);
export let Contact = new ContactModel(realm);
export let Directory = new DirectoryModel(realm);
export let Document = new DocumentModel(realm);
export let SendBrochure = new SendBrochureModel(realm);
export let Setting = new SettingModel(realm);
export let User = new UserModel(realm);

View file

@ -12,7 +12,6 @@ const i18n = new I18n({
i18n.defaultLocale = 'fr';
i18n.locale = 'fr';
i18n.fallbacks = true;
i18n.translations = { fr, en, de };
i18n.enableFallback = true;
export default i18n;

View file

@ -1,4 +1,8 @@
{
"install": {
"install": "Installer",
"installation": "Installation"
},
"global": {
"yes": "Oui",
"no": "Non",

View file

@ -1,64 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class CommonModel {
constructor() {
this.schema = 'Common';
}
add(data) {
realm.write(() => {
if (data.id === undefined) {
let id: any = realm.objects(this.schema).max('id');
data.id = id === undefined ? 1 : id + 1;
}
try {
realm.create(this.schema, data, 'never');
} catch (e) {
console.log('db common add', e);
}
});
}
update(data) {
let tmp = this.get(data.key);
if (tmp === undefined) {
this.add(data);
} else {
if (data.id === undefined) {
data.id = tmp.id;
}
realm.write(() => {
realm.create(this.schema, data, 'modified');
});
}
}
get(key) {
let tmp = realm.objects(this.schema);
if (tmp.length === 0) {
return false;
} else {
tmp = tmp.filtered('key = "' + key + '"')[0];
}
return tmp;
}
getAll() {
let tmp = realm.objects(this.schema);
return tmp;
}
delete(key) {
const tmp = this.get(key);
if (typeof tmp === 'object') {
realm.write(() => {
realm.delete(tmp);
});
}
}
}
export default new CommonModel();

View file

@ -1,60 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class ContactsModel {
constructor() {
this.schema = 'Contacts';
}
add(contact) {
contact.uniq_id = contact.id;
contact.id = undefined;
realm.write(() => {
if (contact.id === undefined) {
let id: any = realm.objects(this.schema).max('id');
contact.id = id === undefined ? 1 : id + 1;
}
realm.create(this.schema, contact);
});
}
update(contact) {
realm.write(() => {
realm.create(this.schema, contact, true);
});
}
get(id) {
let tmp = realm.objects(this.schema).filtered('id = ' + id)[0];
return tmp;
}
getAll() {
let tmp = realm.objects(this.schema);
return tmp;
}
getByUser(userId) {
let tmp = realm.objects(this.schema);
tmp = tmp.filtered('to_delete = false AND user_id = ' + userId);
return tmp;
}
delete(id) {
const tmp = this.get(id);
realm.write(() => {
tmp.to_delete = true;
// HARD DELETE - > realm.delete(tmp);
});
}
clear() {
realm.write(() => {
realm.delete(this.getAll());
});
}
}
export default new ContactsModel();

View file

@ -1,104 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class DirectoriesModel {
constructor() {
this.schema = 'Directories';
}
add(directory) {
realm.write(() => {
realm.create(this.schema, directory);
});
}
update(directory) {
realm.write(() => {
realm.create(this.schema, directory, true);
});
}
get(id) {
let tmp = realm.objects(this.schema).filtered('id = ' + id)[0];
return tmp;
}
getAll(role, authorizedFolders, format, lang) {
if (authorizedFolders !== null && authorizedFolders !== undefined) {
authorizedFolders = JSON.parse(authorizedFolders);
}
let tmp = realm.objects(this.schema);
if (role === 'USER') {
if (authorizedFolders.length > 0) {
tmp = tmp.filtered(
'needAuthorization = 0 OR ' +
authorizedFolders
.map(folder => ' id = "' + folder.id + '"')
.join(' OR '),
);
} else {
tmp = tmp.filtered(
'needAuthorization = 0'
);
}
}
if (format) {
return this._recursiveDir(tmp, lang);
}
return tmp;
}
clear() {
realm.write(() => {
realm.delete(this.getAll('SYNC', null, false));
});
}
_recursiveDir(list, lang, parent = null) {
let root = list.filter(e => e.parent === parent);
let tmp = [];
for (let i = 0; i < root.length; i++) {
let childs = this._recursiveDir(list, lang, root[i].id);
let name = JSON.parse(root[i].name);
tmp[i] = {};
tmp[i].id = root[i].id;
tmp[i].name = this.getI18nName(lang, name);
tmp[i].items = [];
for (let j = 0; j < childs.length; j++) {
childs[j].value = childs[j].id;
tmp[i].items.push(childs[j]);
}
if (!tmp[i].items.length) {
delete tmp[i].items;
}
}
return tmp;
}
getI18nName(lang, name) {
let tmp = undefined;
switch (lang) {
case "fr":
tmp = name.fr;
break;
case "en":
tmp = name.en;
break;
case "de":
tmp = name.de;
break;
case "es":
tmp = name.es;
break;
}
if (tmp === undefined) {
tmp = name.fr;
}
return tmp;
}
}
export default new DirectoriesModel();

View file

@ -1,68 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class DocumentsModel {
constructor() {
this.schema = 'Documents';
}
add(document) {
realm.write(() => {
realm.create(this.schema, document, 'never');
});
}
update(document, updatedAtChange = false) {
let tmp = this.get(document.id);
if (tmp === undefined) {
this.add(document);
} else {
realm.write(() => {
if (updatedAtChange === false) {
realm.create(this.schema, {
id: tmp.id,
uuid: document.uuid,
title: document.title,
type: document.type,
path: document.path,
directory: document.directory
}, 'modified');
} else {
realm.create(this.schema, document, 'modified');
}
});
}
}
get(id) {
let tmp = realm.objects(this.schema).filtered('id = ' + id)[0];
return tmp;
}
getAll(authorizedDirs = false) {
let tmp = realm.objects(this.schema);
if (authorizedDirs) {
authorizedDirs = authorizedDirs.map(item => item.id);
tmp = tmp.filter(doc => authorizedDirs.includes(doc.directory));
}
return tmp;
}
clear(docs, toDelete = []) {
const localDocs = this.getAll();
localDocs.forEach(doc => {
let tmp = docs.filter(item => item.uuid === doc.uuid);
if (tmp.length === 0) {
toDelete.push({uuid: doc.uuid, type: doc.type});
realm.write(() => {
realm.delete(doc);
});
}
});
return toDelete;
}
}
export default new DocumentsModel();

View file

@ -1,49 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class SendBrochureModel {
constructor() {
this.schema = 'SendBrochure';
}
add(data) {
realm.write(() => {
if (data.id === undefined) {
let id: any = realm.objects(this.schema).max('id');
data.id = id === undefined ? 1 : id + 1;
}
realm.create(this.schema, data);
});
}
update(data) {
realm.write(() => {
realm.create(this.schema, data, true);
});
}
get(id) {
let tmp = realm.objects(this.schema);
if (tmp.length === 0) {
return false;
} else {
tmp = tmp.filtered('id = ' + id)[0];
}
return tmp;
}
getAll() {
let tmp = realm.objects(this.schema);
return tmp;
}
clear() {
realm.write(() => {
realm.delete(this.getAll());
});
}
}
export default new SendBrochureModel();

View file

@ -1,40 +0,0 @@
import Database from '../Database';
const Realm = require('realm');
let realm = new Realm(Database);
class UsersModel {
constructor() {
this.schema = 'Users';
}
add(user) {
realm.write(() => {
realm.create(this.schema, user);
});
}
update(user) {
realm.write(() => {
realm.create(this.schema, user, true);
});
}
get(id) {
let tmp = realm.objects(this.schema).filtered('id = ' + id)[0];
return tmp;
}
getAll() {
let tmp = realm.objects(this.schema);
return tmp;
}
clear() {
realm.write(() => {
realm.delete(this.getAll());
});
}
}
export default new UsersModel();

View file

@ -108,7 +108,7 @@ class ContactScreen extends React.Component {
synced: false,
user_id: nextUser.id,
};
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.setState({ showTransferContact: false });
showMessage({
message: i18n.t('contact_s.contact_transferred') + '.',

View file

@ -152,7 +152,7 @@ class ContactDetailsScreen extends React.Component {
};
if (action === 'edit') {
contact.id = this.state.tmpID;
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.populate();
showMessage({
message: i18n.t('contact_details_s.contact_saved') + '.',

View file

@ -152,7 +152,7 @@ class ContactDetailsScreen extends React.Component {
};
if (action === 'edit') {
contact.id = this.state.tmpID;
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.populate();
showMessage({
message: i18n.t('contact_details_s.contact_saved') + '.',

View file

@ -152,7 +152,7 @@ class ContactDetailsScreen extends React.Component {
};
if (action === 'edit') {
contact.id = this.state.tmpID;
this.props.dispatch({ type: 'UPDATE_CONTACT', data: contact });
this.props.dispatch({ type: 'EDIT_CONTACT', data: contact });
this.populate();
showMessage({
message: i18n.t('contact_details_s.contact_saved') + '.',