From 4249eef6539cd2f5b9e05852f4e56e36a5a25853 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Fri, 14 Jan 2022 18:00:04 -0300 Subject: [PATCH 1/8] chore: migrate settings to typescript --- app/actions/settings.js | 21 -------------- app/actions/settings.ts | 34 +++++++++++++++++++++++ app/reducers/settings.test.ts | 31 +++++++++++++++++++++ app/reducers/{settings.js => settings.ts} | 8 ++++-- 4 files changed, 71 insertions(+), 23 deletions(-) delete mode 100644 app/actions/settings.js create mode 100644 app/actions/settings.ts create mode 100644 app/reducers/settings.test.ts rename app/reducers/{settings.js => settings.ts} (57%) diff --git a/app/actions/settings.js b/app/actions/settings.js deleted file mode 100644 index 6fae375b..00000000 --- a/app/actions/settings.js +++ /dev/null @@ -1,21 +0,0 @@ -import { SETTINGS } from './actionsTypes'; - -export function addSettings(settings) { - return { - type: SETTINGS.ADD, - payload: settings - }; -} - -export function updateSettings(id, value) { - return { - type: SETTINGS.UPDATE, - payload: { id, value } - }; -} - -export function clearSettings() { - return { - type: SETTINGS.CLEAR - }; -} diff --git a/app/actions/settings.ts b/app/actions/settings.ts new file mode 100644 index 00000000..6f28570b --- /dev/null +++ b/app/actions/settings.ts @@ -0,0 +1,34 @@ +import { Action } from 'redux'; + +import { ISettings } from '../reducers/settings'; +import { SETTINGS } from './actionsTypes'; + +interface IAddSettings extends Action { + payload: ISettings; +} + +interface IUpdateSettings extends Action { + payload: { id: string; value: string }; +} + +export type IActionSettings = IAddSettings & IUpdateSettings; + +export function addSettings(settings: ISettings): IAddSettings { + return { + type: SETTINGS.ADD, + payload: settings + }; +} + +export function updateSettings(id: string, value: string): IUpdateSettings { + return { + type: SETTINGS.UPDATE, + payload: { id, value } + }; +} + +export function clearSettings(): Action { + return { + type: SETTINGS.CLEAR + }; +} diff --git a/app/reducers/settings.test.ts b/app/reducers/settings.test.ts new file mode 100644 index 00000000..da93ce3c --- /dev/null +++ b/app/reducers/settings.test.ts @@ -0,0 +1,31 @@ +import { addSettings, clearSettings, updateSettings } from '../actions/settings'; +import { mockedStore } from './mockedStore'; +import { initialState } from './settings'; + +describe('test settings reducer', () => { + it('should return initial state', () => { + const state = mockedStore.getState().settings; + expect(state).toEqual(initialState); + }); + + const settings = { API_Use_REST_For_DDP_Calls: true, FileUpload_MaxFileSize: 600857600, Jitsi_URL_Room_Prefix: 'RocketChat' }; + + it('should return modified store after call addSettings action', () => { + mockedStore.dispatch(addSettings(settings)); + const state = mockedStore.getState().settings; + expect(state).toEqual(settings); + }); + + it('should return correctly settings after call updateSettings action', () => { + const id = 'Jitsi_URL_Room_Prefix'; + mockedStore.dispatch(updateSettings(id, 'ChatRocket')); + const state = mockedStore.getState().settings; + expect(state[id]).toEqual('ChatRocket'); + }); + + it('should return initial state after clearSettings', () => { + mockedStore.dispatch(clearSettings()); + const state = mockedStore.getState().settings; + expect(state).toEqual({}); + }); +}); diff --git a/app/reducers/settings.js b/app/reducers/settings.ts similarity index 57% rename from app/reducers/settings.js rename to app/reducers/settings.ts index 6e9ab500..bcaad301 100644 --- a/app/reducers/settings.js +++ b/app/reducers/settings.ts @@ -1,8 +1,12 @@ +import { IActionSettings } from '../actions/settings'; import { SETTINGS } from '../actions/actionsTypes'; -const initialState = {}; +// TODO UPDATE SETTINGS TYPE +export type ISettings = Record; -export default (state = initialState, action) => { +export const initialState: ISettings = {}; + +export default (state = initialState, action: IActionSettings): ISettings => { switch (action.type) { case SETTINGS.ADD: return { From 635d6bf6f399d6c1470ea38b38a59bab1726f314 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Fri, 14 Jan 2022 18:03:16 -0300 Subject: [PATCH 2/8] chore: add interface to IStateAplication --- app/definitions/redux/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index e95763e2..677519c5 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -1,11 +1,13 @@ -import { TActionSelectedUsers } from '../../actions/selectedUsers'; import { TActionActiveUsers } from '../../actions/activeUsers'; +import { TActionSelectedUsers } from '../../actions/selectedUsers'; +import { IActionSettings } from '../../actions/settings'; // REDUCERS import { IActiveUsers } from '../../reducers/activeUsers'; import { ISelectedUsers } from '../../reducers/selectedUsers'; +import { ISettings } from '../../reducers/settings'; export interface IApplicationState { - settings: any; + settings: ISettings; login: any; meteor: any; server: any; @@ -28,4 +30,4 @@ export interface IApplicationState { roles: any; } -export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers; +export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers & IActionSettings; From 89b9e17481f09b4a516d6a4d9520b00be6b75525 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Fri, 14 Jan 2022 19:06:55 -0300 Subject: [PATCH 3/8] chore: migrate redux module room to typescript --- app/actions/rooms.js | 58 ----------------- app/actions/rooms.ts | 78 +++++++++++++++++++++++ app/reducers/rooms.test.ts | 77 ++++++++++++++++++++++ app/reducers/{rooms.js => rooms.ts} | 36 +++++++---- app/views/RoomsListView/Header/index.js | 25 +++----- app/views/RoomsListView/ServerDropdown.js | 35 ++++------ app/views/RoomsListView/index.js | 47 ++++---------- 7 files changed, 212 insertions(+), 144 deletions(-) delete mode 100644 app/actions/rooms.js create mode 100644 app/actions/rooms.ts create mode 100644 app/reducers/rooms.test.ts rename app/reducers/{rooms.js => rooms.ts} (57%) diff --git a/app/actions/rooms.js b/app/actions/rooms.js deleted file mode 100644 index 0f708f8c..00000000 --- a/app/actions/rooms.js +++ /dev/null @@ -1,58 +0,0 @@ -import * as types from './actionsTypes'; - -export function roomsRequest(params = { allData: false }) { - return { - type: types.ROOMS.REQUEST, - params - }; -} - -export function roomsSuccess() { - return { - type: types.ROOMS.SUCCESS - }; -} - -export function roomsFailure(err) { - return { - type: types.ROOMS.FAILURE, - err - }; -} - -export function roomsRefresh() { - return { - type: types.ROOMS.REFRESH - }; -} - -export function setSearch(searchText) { - return { - type: types.ROOMS.SET_SEARCH, - searchText - }; -} - -export function closeServerDropdown() { - return { - type: types.ROOMS.CLOSE_SERVER_DROPDOWN - }; -} - -export function toggleServerDropdown() { - return { - type: types.ROOMS.TOGGLE_SERVER_DROPDOWN - }; -} - -export function openSearchHeader() { - return { - type: types.ROOMS.OPEN_SEARCH_HEADER - }; -} - -export function closeSearchHeader() { - return { - type: types.ROOMS.CLOSE_SEARCH_HEADER - }; -} diff --git a/app/actions/rooms.ts b/app/actions/rooms.ts new file mode 100644 index 00000000..4ce04d86 --- /dev/null +++ b/app/actions/rooms.ts @@ -0,0 +1,78 @@ +import { Action } from 'redux'; + +import { ROOMS } from './actionsTypes'; + +export interface IRoomsRequest extends Action { + params: any; +} + +export interface ISetSearch extends Action { + searchText: string; +} + +export interface IRoomsFailure extends Action { + err: string; +} + +export type IRoomsAction = IRoomsRequest & ISetSearch & IRoomsFailure; + +export function roomsRequest( + params: { + allData: boolean; + } = { allData: false } +): IRoomsRequest { + return { + type: ROOMS.REQUEST, + params + }; +} + +export function roomsSuccess(): Action { + return { + type: ROOMS.SUCCESS + }; +} + +export function roomsFailure(err: string): IRoomsFailure { + return { + type: ROOMS.FAILURE, + err + }; +} + +export function roomsRefresh(): Action { + return { + type: ROOMS.REFRESH + }; +} + +export function setSearch(searchText: string): ISetSearch { + return { + type: ROOMS.SET_SEARCH, + searchText + }; +} + +export function closeServerDropdown(): Action { + return { + type: ROOMS.CLOSE_SERVER_DROPDOWN + }; +} + +export function toggleServerDropdown(): Action { + return { + type: ROOMS.TOGGLE_SERVER_DROPDOWN + }; +} + +export function openSearchHeader(): Action { + return { + type: ROOMS.OPEN_SEARCH_HEADER + }; +} + +export function closeSearchHeader(): Action { + return { + type: ROOMS.CLOSE_SEARCH_HEADER + }; +} diff --git a/app/reducers/rooms.test.ts b/app/reducers/rooms.test.ts new file mode 100644 index 00000000..4bf1312e --- /dev/null +++ b/app/reducers/rooms.test.ts @@ -0,0 +1,77 @@ +import { + closeSearchHeader, + closeServerDropdown, + openSearchHeader, + roomsFailure, + roomsRefresh, + roomsRequest, + roomsSuccess, + setSearch, + toggleServerDropdown +} from '../actions/rooms'; +import { mockedStore } from './mockedStore'; +import { initialState } from './rooms'; + +describe('test selectedUsers reducer', () => { + it('should return initial state', () => { + const state = mockedStore.getState().rooms; + expect(state).toEqual(initialState); + }); + + it('should return modified store after call roomsRequest', () => { + mockedStore.dispatch(roomsRequest()); + const state = mockedStore.getState().rooms; + const manipulated = { ...initialState, isFetching: true, failure: false, errorMessage: {} }; + expect(state).toEqual(manipulated); + }); + + it('should return modified store after call roomsSuccess', () => { + mockedStore.dispatch(roomsSuccess()); + const state = mockedStore.getState().rooms; + const manipulated = { ...initialState, isFetching: false, refreshing: false }; + expect(state).toEqual(manipulated); + }); + + it('should return modified store after call roomsRefresh', () => { + mockedStore.dispatch(roomsRefresh()); + const state = mockedStore.getState().rooms; + const manipulated = { ...initialState, isFetching: true, refreshing: true }; + expect(state).toEqual(manipulated); + }); + + it('should return modified store after call setSearch', () => { + mockedStore.dispatch(setSearch('dog')); + const state = mockedStore.getState().rooms; + expect(state.searchText).toEqual('dog'); + }); + + it('should return modified store after call closeServerDropdown', () => { + mockedStore.dispatch(closeServerDropdown()); + const state = mockedStore.getState().rooms; + expect(state.closeServerDropdown).toEqual(!initialState.closeServerDropdown); + }); + + it('should return modified store after call toggleServerDropdown', () => { + mockedStore.dispatch(toggleServerDropdown()); + const state = mockedStore.getState().rooms; + expect(state.showServerDropdown).toEqual(!initialState.showServerDropdown); + }); + + it('should return modified store after call openSearchHeader', () => { + mockedStore.dispatch(openSearchHeader()); + const state = mockedStore.getState().rooms; + expect(state.showSearchHeader).toEqual(true); + }); + + it('should return modified store after call closeSearchHeader', () => { + mockedStore.dispatch(closeSearchHeader()); + const state = mockedStore.getState().rooms; + expect(state.showSearchHeader).toEqual(false); + }); + + it('should return modified store after call roomsFailure', () => { + mockedStore.dispatch(roomsFailure('error')); + const state = mockedStore.getState().rooms; + expect(state.errorMessage).toEqual('error'); + }); +}); diff --git a/app/reducers/rooms.js b/app/reducers/rooms.ts similarity index 57% rename from app/reducers/rooms.js rename to app/reducers/rooms.ts index 660f5f1e..86a9820f 100644 --- a/app/reducers/rooms.js +++ b/app/reducers/rooms.ts @@ -1,6 +1,18 @@ -import * as types from '../actions/actionsTypes'; +import { IRoomsAction } from '../actions/rooms'; +import { ROOMS } from '../actions/actionsTypes'; -const initialState = { +export interface IRooms { + isFetching: boolean; + refreshing: boolean; + failure: boolean; + errorMessage: Record; + searchText: string; + showServerDropdown: boolean; + closeServerDropdown: boolean; + showSearchHeader: boolean; +} + +export const initialState: IRooms = { isFetching: false, refreshing: false, failure: false, @@ -11,22 +23,22 @@ const initialState = { showSearchHeader: false }; -export default function login(state = initialState, action) { +export default function rooms(state = initialState, action: IRoomsAction): IRooms { switch (action.type) { - case types.ROOMS.REQUEST: + case ROOMS.REQUEST: return { ...state, isFetching: true, failure: false, errorMessage: {} }; - case types.ROOMS.SUCCESS: + case ROOMS.SUCCESS: return { ...state, isFetching: false, refreshing: false }; - case types.ROOMS.FAILURE: + case ROOMS.FAILURE: return { ...state, isFetching: false, @@ -34,33 +46,33 @@ export default function login(state = initialState, action) { failure: true, errorMessage: action.err }; - case types.ROOMS.REFRESH: + case ROOMS.REFRESH: return { ...state, isFetching: true, refreshing: true }; - case types.ROOMS.SET_SEARCH: + case ROOMS.SET_SEARCH: return { ...state, searchText: action.searchText }; - case types.ROOMS.CLOSE_SERVER_DROPDOWN: + case ROOMS.CLOSE_SERVER_DROPDOWN: return { ...state, closeServerDropdown: !state.closeServerDropdown }; - case types.ROOMS.TOGGLE_SERVER_DROPDOWN: + case ROOMS.TOGGLE_SERVER_DROPDOWN: return { ...state, showServerDropdown: !state.showServerDropdown }; - case types.ROOMS.OPEN_SEARCH_HEADER: + case ROOMS.OPEN_SEARCH_HEADER: return { ...state, showSearchHeader: true }; - case types.ROOMS.CLOSE_SEARCH_HEADER: + case ROOMS.CLOSE_SEARCH_HEADER: return { ...state, showSearchHeader: false diff --git a/app/views/RoomsListView/Header/index.js b/app/views/RoomsListView/Header/index.js index b97f65e1..e7735878 100644 --- a/app/views/RoomsListView/Header/index.js +++ b/app/views/RoomsListView/Header/index.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { toggleServerDropdown, closeServerDropdown, setSearch as setSearchAction } from '../../../actions/rooms'; +import { toggleServerDropdown, closeServerDropdown, setSearch } from '../../../actions/rooms'; import { withTheme } from '../../../theme'; import EventEmitter from '../../../utils/events'; import { KEY_COMMAND, handleCommandOpenServerDropdown } from '../../../commands'; @@ -19,10 +19,7 @@ class RoomsListHeaderView extends PureComponent { connected: PropTypes.bool, isFetching: PropTypes.bool, theme: PropTypes.string, - server: PropTypes.string, - open: PropTypes.func, - close: PropTypes.func, - setSearch: PropTypes.func + server: PropTypes.string }; componentDidMount() { @@ -45,17 +42,17 @@ class RoomsListHeaderView extends PureComponent { }; onSearchChangeText = text => { - const { setSearch } = this.props; - setSearch(text.trim()); + const { dispatch } = this.props; + dispatch(setSearch(text.trim())); }; onPress = () => { logEvent(events.RL_TOGGLE_SERVER_DROPDOWN); - const { showServerDropdown, close, open } = this.props; + const { showServerDropdown, dispatch } = this.props; if (showServerDropdown) { - close(); + dispatch(closeServerDropdown()); } else { - open(); + dispatch(toggleServerDropdown()); } }; @@ -89,10 +86,4 @@ const mapStateToProps = state => ({ server: state.server.server }); -const mapDispatchtoProps = dispatch => ({ - close: () => dispatch(closeServerDropdown()), - open: () => dispatch(toggleServerDropdown()), - setSearch: searchText => dispatch(setSearchAction(searchText)) -}); - -export default connect(mapStateToProps, mapDispatchtoProps)(withTheme(RoomsListHeaderView)); +export default connect(mapStateToProps)(withTheme(RoomsListHeaderView)); diff --git a/app/views/RoomsListView/ServerDropdown.js b/app/views/RoomsListView/ServerDropdown.js index 97b52d66..154e5d68 100644 --- a/app/views/RoomsListView/ServerDropdown.js +++ b/app/views/RoomsListView/ServerDropdown.js @@ -6,9 +6,9 @@ import { withSafeAreaInsets } from 'react-native-safe-area-context'; import * as List from '../../containers/List'; import Button from '../../containers/Button'; -import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms'; -import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server'; -import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app'; +import { toggleServerDropdown } from '../../actions/rooms'; +import { selectServerRequest, serverInitAdd } from '../../actions/server'; +import { appStart, ROOT_OUTSIDE } from '../../actions/app'; import RocketChat from '../../lib/rocketchat'; import I18n from '../../i18n'; import EventEmitter from '../../utils/events'; @@ -36,11 +36,7 @@ class ServerDropdown extends Component { closeServerDropdown: PropTypes.bool, server: PropTypes.string, theme: PropTypes.string, - isMasterDetail: PropTypes.bool, - appStart: PropTypes.func, - toggleServerDropdown: PropTypes.func, - selectServerRequest: PropTypes.func, - initAdd: PropTypes.func + isMasterDetail: PropTypes.bool }; constructor(props) { @@ -89,13 +85,13 @@ class ServerDropdown extends Component { } close = () => { - const { toggleServerDropdown } = this.props; + const { dispatch } = this.props; Animated.timing(this.animatedValue, { toValue: 0, duration: ANIMATION_DURATION, easing: Easing.inOut(Easing.quad), useNativeDriver: true - }).start(() => toggleServerDropdown()); + }).start(() => dispatch(toggleServerDropdown())); }; createWorkspace = async () => { @@ -108,10 +104,10 @@ class ServerDropdown extends Component { }; navToNewServer = previousServer => { - const { appStart, initAdd } = this.props; + const { dispatch } = this.props; batch(() => { - appStart({ root: ROOT_OUTSIDE }); - initAdd(previousServer); + dispatch(appStart({ root: ROOT_OUTSIDE })); + dispatch(serverInitAdd(previousServer)); }); }; @@ -125,7 +121,7 @@ class ServerDropdown extends Component { }; select = async (server, version) => { - const { server: currentServer, selectServerRequest, isMasterDetail } = this.props; + const { server: currentServer, dispatch, isMasterDetail } = this.props; this.close(); if (currentServer !== server) { logEvent(events.RL_CHANGE_SERVER); @@ -142,7 +138,7 @@ class ServerDropdown extends Component { }, ANIMATION_DURATION); } else { await localAuthenticate(server); - selectServerRequest(server, version); + dispatch(selectServerRequest(server, version)); } } }; @@ -263,11 +259,4 @@ const mapStateToProps = state => ({ isMasterDetail: state.app.isMasterDetail }); -const mapDispatchToProps = dispatch => ({ - toggleServerDropdown: () => dispatch(toggleServerDropdownAction()), - selectServerRequest: (server, version) => dispatch(selectServerRequestAction(server, version, true, true)), - appStart: params => dispatch(appStartAction(params)), - initAdd: previousServer => dispatch(serverInitAddAction(previousServer)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withSafeAreaInsets(withTheme(ServerDropdown))); +export default connect(mapStateToProps)(withSafeAreaInsets(withTheme(ServerDropdown))); diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 9dc3bca7..1ee94cee 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -12,19 +12,13 @@ import RocketChat from '../../lib/rocketchat'; import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../presentation/RoomItem'; import log, { logEvent, events } from '../../utils/log'; import I18n from '../../i18n'; -import { - closeSearchHeader as closeSearchHeaderAction, - closeServerDropdown as closeServerDropdownAction, - openSearchHeader as openSearchHeaderAction, - roomsRequest as roomsRequestAction -} from '../../actions/rooms'; -import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app'; +import { closeSearchHeader, closeServerDropdown, openSearchHeader, roomsRequest } from '../../actions/rooms'; +import { appStart, ROOT_OUTSIDE } from '../../actions/app'; import debounce from '../../utils/debounce'; import { isIOS, isTablet } from '../../utils/deviceInfo'; import * as HeaderButton from '../../containers/HeaderButton'; import StatusBar from '../../containers/StatusBar'; import ActivityIndicator from '../../containers/ActivityIndicator'; -import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server'; import { animateNextTransition } from '../../utils/layoutAnimation'; import { withTheme } from '../../theme'; import { themes } from '../../constants/colors'; @@ -124,11 +118,6 @@ class RoomsListView extends React.Component { refreshing: PropTypes.bool, StoreLastMessage: PropTypes.bool, theme: PropTypes.string, - openSearchHeader: PropTypes.func, - closeSearchHeader: PropTypes.func, - appStart: PropTypes.func, - roomsRequest: PropTypes.func, - closeServerDropdown: PropTypes.func, useRealName: PropTypes.bool, isMasterDetail: PropTypes.bool, rooms: PropTypes.array, @@ -169,7 +158,7 @@ class RoomsListView extends React.Component { } componentDidMount() { - const { navigation, closeServerDropdown } = this.props; + const { navigation, dispatch } = this.props; this.handleHasPermission(); this.mounted = true; @@ -193,7 +182,7 @@ class RoomsListView extends React.Component { }); this.unsubscribeBlur = navigation.addListener('blur', () => { this.animated = false; - closeServerDropdown(); + dispatch(closeServerDropdown()); this.cancelSearch(); if (this.backHandler && this.backHandler.remove) { this.backHandler.remove(); @@ -553,9 +542,9 @@ class RoomsListView extends React.Component { initSearching = () => { logEvent(events.RL_SEARCH); - const { openSearchHeader } = this.props; + const { dispatch } = this.props; this.internalSetState({ searching: true }, () => { - openSearchHeader(); + dispatch(openSearchHeader()); this.search(''); this.setHeader(); }); @@ -563,7 +552,7 @@ class RoomsListView extends React.Component { cancelSearch = () => { const { searching } = this.state; - const { closeSearchHeader } = this.props; + const { dispatch } = this.props; if (!searching) { return; @@ -573,7 +562,7 @@ class RoomsListView extends React.Component { this.setState({ searching: false, search: [] }, () => { this.setHeader(); - closeSearchHeader(); + dispatch(closeSearchHeader()); setTimeout(() => { this.scrollToTop(); }, 200); @@ -842,7 +831,7 @@ class RoomsListView extends React.Component { }; handleCommands = ({ event }) => { - const { navigation, server, isMasterDetail, appStart, initAdd } = this.props; + const { navigation, server, isMasterDetail, dispatch, initAdd } = this.props; const { input } = event; if (handleCommandShowPreferences(event)) { navigation.navigate('SettingsView'); @@ -862,7 +851,7 @@ class RoomsListView extends React.Component { } } else if (handleCommandAddNewServer(event)) { batch(() => { - appStart({ root: ROOT_OUTSIDE }); + dispatch(appStart({ root: ROOT_OUTSIDE })); initAdd(server); }); } @@ -870,11 +859,11 @@ class RoomsListView extends React.Component { onRefresh = () => { const { searching } = this.state; - const { roomsRequest } = this.props; + const { dispatch } = this.props; if (searching) { return; } - roomsRequest({ allData: true }); + dispatch(roomsRequest({ allData: true })); }; onEndReached = () => { @@ -1045,14 +1034,4 @@ const mapStateToProps = state => ({ createDiscussionPermission: state.permissions['start-discussion'] }); -const mapDispatchToProps = dispatch => ({ - openSearchHeader: () => dispatch(openSearchHeaderAction()), - closeSearchHeader: () => dispatch(closeSearchHeaderAction()), - roomsRequest: params => dispatch(roomsRequestAction(params)), - selectServerRequest: server => dispatch(selectServerRequestAction(server)), - closeServerDropdown: () => dispatch(closeServerDropdownAction()), - appStart: params => dispatch(appStartAction(params)), - initAdd: previousServer => dispatch(serverInitAddAction(previousServer)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView)))); +export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView)))); From 1c5d442712a05c686a8438f32e84a59674229bb1 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Mon, 17 Jan 2022 11:20:29 -0300 Subject: [PATCH 4/8] chore: fix error on error interface --- app/actions/rooms.ts | 2 +- app/reducers/rooms.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/actions/rooms.ts b/app/actions/rooms.ts index 4ce04d86..514582ff 100644 --- a/app/actions/rooms.ts +++ b/app/actions/rooms.ts @@ -11,7 +11,7 @@ export interface ISetSearch extends Action { } export interface IRoomsFailure extends Action { - err: string; + err: Record | string; } export type IRoomsAction = IRoomsRequest & ISetSearch & IRoomsFailure; diff --git a/app/reducers/rooms.ts b/app/reducers/rooms.ts index 86a9820f..1a670508 100644 --- a/app/reducers/rooms.ts +++ b/app/reducers/rooms.ts @@ -5,7 +5,7 @@ export interface IRooms { isFetching: boolean; refreshing: boolean; failure: boolean; - errorMessage: Record; + errorMessage: Record | string; searchText: string; showServerDropdown: boolean; closeServerDropdown: boolean; From 8d22b8425342023eabbf5c587d399aeab4fd8bc9 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Mon, 17 Jan 2022 15:16:24 -0300 Subject: [PATCH 5/8] chore: migrate redux module roles to typescript --- app/actions/roles.js | 20 --------------- app/actions/roles.ts | 39 +++++++++++++++++++++++++++++ app/definitions/redux/index.ts | 5 ++-- app/reducers/roles.test.ts | 35 ++++++++++++++++++++++++++ app/reducers/{roles.js => roles.ts} | 7 ++++-- 5 files changed, 82 insertions(+), 24 deletions(-) delete mode 100644 app/actions/roles.js create mode 100644 app/actions/roles.ts create mode 100644 app/reducers/roles.test.ts rename app/reducers/{roles.js => roles.ts} (63%) diff --git a/app/actions/roles.js b/app/actions/roles.js deleted file mode 100644 index 8ee30425..00000000 --- a/app/actions/roles.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as types from './actionsTypes'; - -export function setRoles(roles) { - return { - type: types.ROLES.SET, - roles - }; -} -export function updateRoles(id, desc) { - return { - type: types.ROLES.UPDATE, - payload: { id, desc } - }; -} -export function removeRoles(id) { - return { - type: types.ROLES.REMOVE, - payload: { id } - }; -} diff --git a/app/actions/roles.ts b/app/actions/roles.ts new file mode 100644 index 00000000..3dbfa370 --- /dev/null +++ b/app/actions/roles.ts @@ -0,0 +1,39 @@ +import { Action } from 'redux'; + +import { IRoles } from '../reducers/roles'; +import { ROLES } from './actionsTypes'; + +export interface ISetRoles extends Action { + roles: IRoles; +} + +export interface IUpdateRoles extends Action { + payload: { id: string; desc: string }; +} + +export interface IRemoveRoles extends Action { + payload: { id: string }; +} + +export type IActionRoles = ISetRoles & IUpdateRoles & IRemoveRoles; + +export function setRoles(roles: IRoles): ISetRoles { + return { + type: ROLES.SET, + roles + }; +} + +export function updateRoles(id: string, desc: string): IUpdateRoles { + return { + type: ROLES.UPDATE, + payload: { id, desc } + }; +} + +export function removeRoles(id: string): IRemoveRoles { + return { + type: ROLES.REMOVE, + payload: { id } + }; +} diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index e95763e2..36d7c0ea 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -1,5 +1,6 @@ -import { TActionSelectedUsers } from '../../actions/selectedUsers'; import { TActionActiveUsers } from '../../actions/activeUsers'; +import { IActionRoles } from '../../actions/roles'; +import { TActionSelectedUsers } from '../../actions/selectedUsers'; // REDUCERS import { IActiveUsers } from '../../reducers/activeUsers'; import { ISelectedUsers } from '../../reducers/selectedUsers'; @@ -28,4 +29,4 @@ export interface IApplicationState { roles: any; } -export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers; +export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers & IActionRoles; diff --git a/app/reducers/roles.test.ts b/app/reducers/roles.test.ts new file mode 100644 index 00000000..8348a871 --- /dev/null +++ b/app/reducers/roles.test.ts @@ -0,0 +1,35 @@ +import { setRoles, updateRoles, removeRoles } from '../actions/roles'; +import { mockedStore } from './mockedStore'; +import { initialState } from './roles'; + +describe('test roles reducer', () => { + it('should return initial state', () => { + const state = mockedStore.getState().roles; + expect(state).toEqual(initialState); + }); + + it('should return modified store after call setRoles action', () => { + const roles = { admin: 'enabled', user: 'enabled', dog: 'carlitos' }; + mockedStore.dispatch(setRoles(roles)); + const state = mockedStore.getState().roles; + expect(state.admin).toEqual('enabled'); + expect(state.user).toEqual('enabled'); + expect(state.dog).toEqual('carlitos'); + }); + + it('should return modified store after call updateRoles action', () => { + mockedStore.dispatch(updateRoles('admin', 'disabled')); + const state = mockedStore.getState().roles; + expect(state.admin).toEqual('disabled'); + expect(state.user).toEqual('enabled'); + expect(state.dog).toEqual('carlitos'); + }); + + it('should return modified store after call removeRoles action', () => { + mockedStore.dispatch(removeRoles('dog')); + const state = mockedStore.getState().roles; + expect(state.admin).toEqual('disabled'); + expect(state.user).toEqual('enabled'); + expect(state.dog).toEqual(undefined); + }); +}); diff --git a/app/reducers/roles.js b/app/reducers/roles.ts similarity index 63% rename from app/reducers/roles.js rename to app/reducers/roles.ts index 93cbffcb..fc4f1124 100644 --- a/app/reducers/roles.js +++ b/app/reducers/roles.ts @@ -1,8 +1,11 @@ import { ROLES } from '../actions/actionsTypes'; +import { IActionRoles } from '../actions/roles'; -const initialState = {}; +export type IRoles = Record; -export default function permissions(state = initialState, action) { +export const initialState: IRoles = {}; + +export default function roles(state = initialState, action: IActionRoles): IRoles { switch (action.type) { case ROLES.SET: return action.roles; From 01fca753b624139ac8ec0c7831feada443a356d0 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Mon, 17 Jan 2022 15:29:37 -0300 Subject: [PATCH 6/8] wip: add IRoles to IAplicationState interface --- app/definitions/redux/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index 36d7c0ea..1ef398a8 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -3,6 +3,7 @@ import { IActionRoles } from '../../actions/roles'; import { TActionSelectedUsers } from '../../actions/selectedUsers'; // REDUCERS import { IActiveUsers } from '../../reducers/activeUsers'; +import { IRoles } from '../../reducers/roles'; import { ISelectedUsers } from '../../reducers/selectedUsers'; export interface IApplicationState { @@ -26,7 +27,7 @@ export interface IApplicationState { enterpriseModules: any; encryption: any; permissions: any; - roles: any; + roles: IRoles; } export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers & IActionRoles; From 4fad0cafad08fef1d2aacbdf541ee3a0e1d650e2 Mon Sep 17 00:00:00 2001 From: GleidsonDaniel Date: Thu, 20 Jan 2022 14:41:04 -0300 Subject: [PATCH 7/8] chore: update settings value types --- app/actions/settings.ts | 6 +++--- app/reducers/settings.ts | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/actions/settings.ts b/app/actions/settings.ts index 6f28570b..77b8dcc7 100644 --- a/app/actions/settings.ts +++ b/app/actions/settings.ts @@ -1,6 +1,6 @@ import { Action } from 'redux'; -import { ISettings } from '../reducers/settings'; +import { ISettings, TSettings } from '../reducers/settings'; import { SETTINGS } from './actionsTypes'; interface IAddSettings extends Action { @@ -8,7 +8,7 @@ interface IAddSettings extends Action { } interface IUpdateSettings extends Action { - payload: { id: string; value: string }; + payload: { id: string; value: TSettings }; } export type IActionSettings = IAddSettings & IUpdateSettings; @@ -20,7 +20,7 @@ export function addSettings(settings: ISettings): IAddSettings { }; } -export function updateSettings(id: string, value: string): IUpdateSettings { +export function updateSettings(id: string, value: TSettings): IUpdateSettings { return { type: SETTINGS.UPDATE, payload: { id, value } diff --git a/app/reducers/settings.ts b/app/reducers/settings.ts index bcaad301..028431ed 100644 --- a/app/reducers/settings.ts +++ b/app/reducers/settings.ts @@ -1,8 +1,9 @@ import { IActionSettings } from '../actions/settings'; import { SETTINGS } from '../actions/actionsTypes'; -// TODO UPDATE SETTINGS TYPE -export type ISettings = Record; +export type TSettings = string | number | boolean; + +export type ISettings = Record; export const initialState: ISettings = {}; From ddd0a845300f49871bc91b5cf1dca3a2113a471a Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 20 Jan 2022 14:45:40 -0300 Subject: [PATCH 8/8] Send missing params to selectServerRequest --- app/views/RoomsListView/ServerDropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/RoomsListView/ServerDropdown.js b/app/views/RoomsListView/ServerDropdown.js index 154e5d68..8dd42ee9 100644 --- a/app/views/RoomsListView/ServerDropdown.js +++ b/app/views/RoomsListView/ServerDropdown.js @@ -138,7 +138,7 @@ class ServerDropdown extends Component { }, ANIMATION_DURATION); } else { await localAuthenticate(server); - dispatch(selectServerRequest(server, version)); + dispatch(selectServerRequest(server, version, true, true)); } } };