Browse Source

Merge branch 'fix/permission-actions' into 'master'

FIX | issue with no permissions user tasks actions

See merge request jetup/rws/rws-appication!361
merge-requests/362/head
Coder 2 years ago
parent
commit
3dba672faa
  1. 16
      ios/Podfile.lock
  2. 4
      ios/taskme.xcodeproj/project.pbxproj
  3. 16
      src/modules/root/hooks/use-app-socket-listener.hook.ts
  4. 18
      src/modules/tasks/components/actions-for-selected-items-row.component.tsx
  5. 4
      src/modules/tasks/components/tasks-list-with-header.component.tsx
  6. 29
      src/modules/tasks/config/selected-tasks-menu-options.config.ts
  7. 5
      src/modules/tasks/config/task-attachments-menu.config.ts
  8. 33
      src/modules/tasks/config/task-card-buttons.config.ts
  9. 13
      src/modules/tasks/config/task-menu-options.config.ts
  10. 85
      src/modules/tasks/helpers/index.ts
  11. 2
      src/modules/tasks/screens/filter-tasks-result.screen.tsx
  12. 14
      src/modules/tasks/screens/task-details.screen.tsx
  13. 22
      src/modules/tasks/smart-components/swipable-task-card.smart-component.tsx
  14. 10
      src/modules/tasks/smart-components/tasks-list-head.smart-component.tsx
  15. 2
      src/modules/tasks/smart-components/tasks-list.smart-component.tsx
  16. 1
      src/services/system/real-time.service.ts
  17. 3
      src/shared/events/index.ts
  18. 2
      src/shared/themes/dark/task-card.ts
  19. 4
      src/shared/themes/interfaces/task-card.interface.ts
  20. 6
      src/shared/themes/light/task-card.ts

16
ios/Podfile.lock

@ -9,9 +9,9 @@ PODS: @@ -9,9 +9,9 @@ PODS:
- React-Core (= 0.66.4)
- React-jsi (= 0.66.4)
- ReactCommon/turbomodule/core (= 0.66.4)
- ffmpeg-kit-ios-full (4.5.1)
- ffmpeg-kit-react-native/full (4.5.2):
- ffmpeg-kit-ios-full (= 4.5.1)
- ffmpeg-kit-ios-audio (4.5.1)
- ffmpeg-kit-react-native/audio (4.5.2):
- ffmpeg-kit-ios-audio (= 4.5.1)
- React-Core
- fmt (6.2.1)
- glog (0.3.5)
@ -444,7 +444,7 @@ DEPENDENCIES: @@ -444,7 +444,7 @@ DEPENDENCIES:
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- ffmpeg-kit-react-native/full (from `../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec`)
- ffmpeg-kit-react-native/audio (from `../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- OneSignal (< 4.0, >= 3.0)
- Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`)
@ -516,7 +516,7 @@ DEPENDENCIES: @@ -516,7 +516,7 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- ffmpeg-kit-ios-full
- ffmpeg-kit-ios-audio
- fmt
- libwebp
- OneSignal
@ -672,7 +672,7 @@ SPEC CHECKSUMS: @@ -672,7 +672,7 @@ SPEC CHECKSUMS:
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: e5569e42a1c79ca00521846c223173a57aca1fe1
FBReactNativeSpec: fe08c1cd7e2e205718d77ad14b34957cce949b58
ffmpeg-kit-ios-full: 1e918caa885a00501ec1606c68a874d07d681705
ffmpeg-kit-ios-audio: 662ce2064e56733ca7d8216705efbc38d9e1c3fe
ffmpeg-kit-react-native: bc3c900af9f761b6fe30906ee1bd98000c79f9c9
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 5337263514dd6f09803962437687240c5dc39aa4
@ -747,6 +747,6 @@ SPEC CHECKSUMS: @@ -747,6 +747,6 @@ SPEC CHECKSUMS:
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280
PODFILE CHECKSUM: a76c90056fe549e78e6914a0ebf8f81ff8b1ae62
PODFILE CHECKSUM: d1cd3b32af0702e70a0ab15184e7f8457bfcc729
COCOAPODS: 1.11.3
COCOAPODS: 1.11.2

4
ios/taskme.xcodeproj/project.pbxproj

@ -863,7 +863,7 @@ @@ -863,7 +863,7 @@
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -928,7 +928,7 @@ @@ -928,7 +928,7 @@
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;

16
src/modules/root/hooks/use-app-socket-listener.hook.ts

@ -1,12 +1,22 @@ @@ -1,12 +1,22 @@
import { chatMessageManager } from '@/managers/chat-message.manager'
import { authService, taxonomiesService } from '@/services/domain'
import {
authService,
permissionsService,
taxonomiesService,
} from '@/services/domain'
import { SocketEvents, useSocketListener } from '@/shared'
export const useAppSocketListener = () => {
const onStopSession = async () => await authService.stopSession()
const onChangedUserPermissions = async () => {
console.log('permission changed')
await permissionsService.loadPermissionsForUsers()
}
const onNewTaxonomy = async (data: SocketEvents['taxonomy/new']) =>
await taxonomiesService.onNewTaxonomy(data)
// ********************************
// Після успішного збереження повідомлень, надісланих офлайн, на бекенді з затримкою кидається даний сокет сигнал
// Використовується для того, щоб замінити дані повідомлення в локальній бд на реальні повідомлення
@ -30,4 +40,6 @@ export const useAppSocketListener = () => { @@ -30,4 +40,6 @@ export const useAppSocketListener = () => {
useSocketListener('taxonomy/new', onNewTaxonomy, [])
useSocketListener('chat/new-message-offline', onNewMessageOffline, [])
useSocketListener('user/change-permissions', onChangedUserPermissions, [])
}

18
src/modules/tasks/components/actions-for-selected-items-row.component.tsx

@ -6,6 +6,7 @@ import { @@ -6,6 +6,7 @@ import {
ITaskActionPayload,
ITaskDetails,
ITaskPreview,
IUser,
RoundButton,
TaskStatus,
Txt,
@ -15,12 +16,17 @@ import { PartialTheme } from '@/shared/themes/interfaces' @@ -15,12 +16,17 @@ import { PartialTheme } from '@/shared/themes/interfaces'
import { View, StyleSheet, ViewStyle } from 'react-native'
import { ActionsIconsForSelected } from '../atoms'
import _ from 'lodash'
import { checkIsTaskActionPossibleByUser } from '../helpers'
interface IProps {
title: string
style?: ViewStyle
taskIds: (number | string)[]
tasks?: ITaskDetails[]
tasks?: ITaskPreview[]
user?: IUser
permissions?: {
[x: string]: string[]
}
dates: string[]
onPressActionIcon: (
action: FullTaskActions,
@ -47,6 +53,16 @@ export const ActionsForSelectedItemsRow: FC<IProps> = ({ @@ -47,6 +53,16 @@ export const ActionsForSelectedItemsRow: FC<IProps> = ({
if (_.isEmpty(tasks)) return result
tasks.forEach(it => {
const availableOptions = checkIsTaskActionPossibleByUser(
props.user,
it.authorId,
it.executor.id,
props.permissions,
)
if (!availableOptions.canDestroy) result.hasRemoved = true
if (!availableOptions.canUpdate) result.hasFinished = true
if (it.doneDate) result.hasFinished = true
if (it.status === TaskStatus.Deleted) {
result.hasRemoved = true

4
src/modules/tasks/components/tasks-list-with-header.component.tsx

@ -7,7 +7,6 @@ import { @@ -7,7 +7,6 @@ import {
} from '@/shared'
import { useTheme } from '@/shared/hooks/use-theme.hook'
import { PartialTheme } from '@/shared/themes/interfaces'
import { selectAccount } from '@/store/account'
import _ from 'lodash'
import React, { FC } from 'react'
import {
@ -17,7 +16,6 @@ import { @@ -17,7 +16,6 @@ import {
Text,
ActivityIndicator,
} from 'react-native'
import { useSelector } from 'react-redux'
import { TasksListHeader } from '../atoms'
import { createCardStyles, isOverdueCheck } from '../helpers'
import { SwipableTaskCard } from '../smart-components'
@ -60,6 +58,8 @@ export const TasksListWithHeader: FC<IProps> = ({ @@ -60,6 +58,8 @@ export const TasksListWithHeader: FC<IProps> = ({
<SwipableTaskCard
key={item.id.toString()}
id={item.id}
authorId={item.authorId}
executorId={item.executor.id}
isRead={item.isRead}
isFavorite={item.isFavorite}
hasComments={item?.hasComments}

29
src/modules/tasks/config/selected-tasks-menu-options.config.ts

@ -1,18 +1,28 @@ @@ -1,18 +1,28 @@
import {
appEvents,
EUserRole,
FullTaskActions,
ITaskActionPayload,
ITaskPreview,
IUser,
RouteKey,
TaskStatus,
} from '@/shared'
import _ from 'lodash'
import { checkIsTaskActionPossibleByUser } from '../helpers'
interface IMenuOption {
name: string
onPress: () => void
}
const getSummary = (tasks: ITaskPreview[]) => {
const getSummary = (
tasks: ITaskPreview[],
user: IUser,
permissions: {
[x: string]: string[]
},
) => {
const result = {
hasFinished: false,
hasRemoved: false,
@ -22,7 +32,18 @@ const getSummary = (tasks: ITaskPreview[]) => { @@ -22,7 +32,18 @@ const getSummary = (tasks: ITaskPreview[]) => {
if (_.isEmpty(tasks)) return result
tasks.forEach(it => {
const availableOptions = checkIsTaskActionPossibleByUser(
user,
it.authorId,
it.executor.id,
permissions,
)
if (!availableOptions.canDestroy) result.hasRemoved = true
if (!availableOptions.canUpdate) result.hasFinished = true
if (it.doneDate) result.hasFinished = true
if (it.status === TaskStatus.Deleted) {
result.hasRemoved = true
result.hasFinished = true
@ -38,6 +59,10 @@ const getSummary = (tasks: ITaskPreview[]) => { @@ -38,6 +59,10 @@ const getSummary = (tasks: ITaskPreview[]) => {
}
export const getSelectedTasksMenuOptions = (
user: IUser,
permissions: {
[x: string]: string[]
},
tasks: ITaskPreview[],
navigate: (key: RouteKey, params?: Record<any, any>) => void,
actions: {
@ -48,7 +73,7 @@ export const getSelectedTasksMenuOptions = ( @@ -48,7 +73,7 @@ export const getSelectedTasksMenuOptions = (
) => void
},
) => {
const summary = getSummary(tasks)
const summary = getSummary(tasks, user, permissions)
const result = []

5
src/modules/tasks/config/task-attachments-menu.config.ts

@ -1,8 +1,5 @@ @@ -1,8 +1,5 @@
import { TaskAttachmentsActionMode } from './../enum/task-attachments.enums'
import {
alertNotAllowedFiles,
checkTaskFiles,
} from '@/shared/helpers'
import { alertNotAllowedFiles, checkTaskFiles } from '@/shared/helpers'
import { mediaService } from '@/services/system'
import _ from 'lodash'
import { appEvents, IFile } from '@/shared'

33
src/modules/tasks/config/task-card-buttons.config.ts

@ -5,21 +5,33 @@ import { @@ -5,21 +5,33 @@ import {
ITaskActionPayload,
TaskStatus,
} from '@/shared'
import { getCurrentThemeType } from '@/shared/helpers'
export const getTaskCardButtons = (
id: number | string,
date: string,
isTaskFavorite: boolean,
isAccessibleAction: {
canUpdate: boolean
canDestroy: boolean
},
onPress: (action: FullTaskActions, payload: ITaskActionPayload) => void,
status: TaskStatus,
closeSwipeable,
) => {
const theme = getCurrentThemeType()
const deleteBtn = {
title: 'Видалити',
bgColor: getTheme().$deleteBtn,
txtColor: getTheme().$deleteText,
bgColor: !isAccessibleAction.canDestroy
? getTheme(theme).$unAccessibleBtn
: getTheme(theme).$deleteBtn,
txtColor: !isAccessibleAction.canDestroy
? getTheme(theme).$unAccessibleTxt
: getTheme(theme).$deleteText,
iconName: 'bin',
onPress: () => {
if (!isAccessibleAction.canDestroy) return
closeSwipeable()
appEvents.emit('openConfirmModal', {
title: 'Видалити задачу?',
@ -27,15 +39,15 @@ export const getTaskCardButtons = ( @@ -27,15 +39,15 @@ export const getTaskCardButtons = (
allowBtnAction: () => {
setTimeout(() => onPress(FullTaskActions.Destroy, {}), 300)
},
notAllowBtnAction: () => { },
notAllowBtnAction: () => {},
})
},
}
const result = [
{
title: 'Обрана',
bgColor: getTheme().$pinBtn,
txtColor: getTheme().$pinText,
bgColor: getTheme(theme).$pinBtn,
txtColor: getTheme(theme).$pinText,
iconName: 'vectorstart',
onPress: () => {
closeSwipeable()
@ -51,7 +63,7 @@ export const getTaskCardButtons = ( @@ -51,7 +63,7 @@ export const getTaskCardButtons = (
else onPress(FullTaskActions.AddFavorite, {})
}, 500)
},
notAllowBtnAction: () => { },
notAllowBtnAction: () => {},
})
},
},
@ -62,10 +74,15 @@ export const getTaskCardButtons = ( @@ -62,10 +74,15 @@ export const getTaskCardButtons = (
result.unshift(deleteBtn)
result.unshift({
title: 'Виконати',
bgColor: getTheme().$doneBtn,
txtColor: getTheme().$doneText,
bgColor: !isAccessibleAction.canUpdate
? getTheme(theme).$unAccessibleBtn
: getTheme(theme).$doneBtn,
txtColor: !isAccessibleAction.canUpdate
? getTheme(theme).$unAccessibleTxt
: getTheme(theme).$doneText,
iconName: 'checks-1',
onPress: () => {
if (!isAccessibleAction.canUpdate) return
closeSwipeable()
appEvents.emit('openFinishTasksModal', {
taskIds: [id],

13
src/modules/tasks/config/task-menu-options.config.ts

@ -71,6 +71,10 @@ const createMenuOptions = ( @@ -71,6 +71,10 @@ const createMenuOptions = (
export const getMenuOptions = (
task: ITaskPreview,
isAccessibleAction: {
canUpdate: boolean
canDestroy: boolean
},
navigate: (key: RouteKey, params?: Record<any, any>) => void,
onPressRemove: () => void,
onPressAction: (
@ -88,6 +92,15 @@ export const getMenuOptions = ( @@ -88,6 +92,15 @@ export const getMenuOptions = (
const commonOptions = [menuOptions.copy, menuOptions.print]
if (!isAccessibleAction.canDestroy) {
delete menuOptions.delete
delete menuOptions.change_executor
}
if (!isAccessibleAction.canUpdate) {
delete menuOptions.edit
delete menuOptions.done
}
const menuOptionsByTaskStatus: Record<TaskStatus, IMenuOption[]> = {
[TaskStatus.Active]: Object.values(menuOptions),
[TaskStatus.Deleted]: commonOptions,

85
src/modules/tasks/helpers/index.ts

@ -1,21 +1,32 @@ @@ -1,21 +1,32 @@
import { IFullTaskInfo, ITaskPreview, TaskEvent, TaskStatus } from '@/shared'
import {
EUserRole,
IFullTaskInfo,
ITaskPreview,
IUser,
TaskEvent,
TaskStatus,
} from '@/shared'
import _ from 'lodash'
import moment from 'moment'
export const taskStatuses = {
'active': 'Активні',
'finished': 'Виконані',
'deleted': 'Видалені'
active: 'Активні',
finished: 'Виконані',
deleted: 'Видалені',
}
export const checkIsTaskReadByUser = (
task: Pick<ITaskPreview & {events?: Record<string, TaskEvent[]>}, 'events'> | Pick<IFullTaskInfo & {events?: Record<string, TaskEvent[]>}, 'events'>,
task:
| Pick<
ITaskPreview & { events?: Record<string, TaskEvent[]> },
'events'
>
| Pick<
IFullTaskInfo & { events?: Record<string, TaskEvent[]> },
'events'
>,
userId: number,
) =>
_.some(
task?.events,
event => event[`${userId}`] === TaskEvent.Read,
)
) => _.some(task?.events, event => event[`${userId}`] === TaskEvent.Read)
export const isUserOwnTask = (
task: ITaskPreview | IFullTaskInfo,
@ -23,7 +34,7 @@ export const isUserOwnTask = ( @@ -23,7 +34,7 @@ export const isUserOwnTask = (
) => task?.executor?.id === userId
export const isOverdueCheck = (endDate: string, status: TaskStatus) =>
moment(new Date()).isAfter(endDate) && status === TaskStatus.Active
moment(new Date()).isAfter(endDate) && status === TaskStatus.Active
export const createCardStyles = (items: any[], index: number) => {
let styles: any
@ -38,8 +49,54 @@ export const createCardStyles = (items: any[], index: number) => { @@ -38,8 +49,54 @@ export const createCardStyles = (items: any[], index: number) => {
borderBottomWidth: 0,
}
if (items?.length === 1)
styles = { borderRadius: 20, borderBottomWidth: 0 }
if (items?.length === 1) styles = { borderRadius: 20, borderBottomWidth: 0 }
return styles
}
}
export const checkIsTaskActionPossibleByUser = (
user: IUser,
authorId: number,
executorId: number,
permissions?: {
[x: string]: string[]
},
) => {
const result = {
canUpdate: false,
canDestroy: false,
}
if (user.role === EUserRole.Admin) {
result.canDestroy = true
result.canUpdate = true
return result
}
if (user.id === authorId && user.id === executorId) {
result.canDestroy = true
result.canUpdate = true
return result
}
if (
permissions &&
permissions.user &&
!_.isEmpty(permissions.user[executorId]) &&
permissions.user[executorId].includes('update')
) {
result.canUpdate = true
}
if (
permissions &&
permissions.user &&
!_.isEmpty(permissions.user[executorId]) &&
permissions.user[executorId].includes('destroy')
)
result.canDestroy = true
return result
}

2
src/modules/tasks/screens/filter-tasks-result.screen.tsx

@ -95,6 +95,8 @@ export const FilterTasksResultScreen: FC<IProps> = ({ route, navigation }) => { @@ -95,6 +95,8 @@ export const FilterTasksResultScreen: FC<IProps> = ({ route, navigation }) => {
<SwipableTaskCard
key={item.id.toString()}
id={item.id}
authorId={item.authorId}
executorId={item.executor.id}
hasComments={item?.hasComments}
hasUnreadComments={item.hasUnreadComments}
isFavorite={item.isFavorite}

14
src/modules/tasks/screens/task-details.screen.tsx

@ -24,6 +24,10 @@ import { getMenuOptions, getTaskDetailsRows, getTaskTerms } from '../config' @@ -24,6 +24,10 @@ import { getMenuOptions, getTaskDetailsRows, getTaskTerms } from '../config'
import { TaskAttachmentsActionMode } from '../enum'
import { useReasons, useTaskActions, useTaskDetails } from '../hooks'
import { TaskAttachmentsCollapseSmart } from '../smart-components'
import { useSelector } from 'react-redux'
import { selectAccount } from '@/store/account'
import { checkIsTaskActionPossibleByUser } from '../helpers'
import { selectPermissionsForUsers } from '@/store/permissions'
interface IProps extends IRouteParams {
route: {
@ -40,6 +44,8 @@ export const TaskDetailsScreen: FC<IProps> = ({ @@ -40,6 +44,8 @@ export const TaskDetailsScreen: FC<IProps> = ({
const { styles, theme } = useTheme(createStyles)
const nav = useNav()
const { id, isLoading, taskDetails, reload } = useTaskDetails(params.taskId)
const account = useSelector(selectAccount)
const permissions = useSelector(selectPermissionsForUsers)
const {
activeReason,
@ -60,9 +66,17 @@ export const TaskDetailsScreen: FC<IProps> = ({ @@ -60,9 +66,17 @@ export const TaskDetailsScreen: FC<IProps> = ({
await handleDeleteTask(taskDetails as any, () => nav.goBack())
}
const isAccessibleAction = checkIsTaskActionPossibleByUser(
account,
taskDetails?.authorId,
taskDetails?.executorId,
permissions,
)
const openMenu = () => {
const menuOptions = getMenuOptions(
taskDetails as any,
isAccessibleAction,
nav.navigate,
deleteTask,
handlePressOneTaskAction,

22
src/modules/tasks/smart-components/swipable-task-card.smart-component.tsx

@ -6,17 +6,23 @@ import { @@ -6,17 +6,23 @@ import {
} from '@/shared'
import { useTheme } from '@/shared/hooks/use-theme.hook'
import { PartialTheme } from '@/shared/themes/interfaces'
import { useFocusEffect } from '@react-navigation/native'
import _ from 'lodash'
import React, { FC, useEffect, useMemo, useRef } from 'react'
import { StyleSheet, View } from 'react-native'
import { Swipeable } from 'react-native-gesture-handler'
import { TaskCard } from '../components'
import { getTaskCardButtons } from '../config'
import { useSelector } from 'react-redux'
import { selectAccount } from '@/store/account'
import { checkIsTaskActionPossibleByUser } from '../helpers'
import { selectPermissionsForUsers } from '@/store/permissions'
import { getCurrentThemeType } from '@/shared/helpers'
interface IProps {
id: number | string
userName?: string
authorId: number
executorId: number
imageUrl?: string
title?: string
date?: string
@ -43,11 +49,23 @@ interface IProps { @@ -43,11 +49,23 @@ interface IProps {
export const SwipableTaskCard: FC<IProps> = ({ onPress, ...props }) => {
const { styles, theme } = useTheme(createStyles)
const account = useSelector(selectAccount)
const permissions = useSelector(selectPermissionsForUsers)
const appTheme = getCurrentThemeType()
const isAccessible = checkIsTaskActionPossibleByUser(
account,
props.authorId,
props.executorId,
permissions,
)
const btnsConfig = getTaskCardButtons(
props.id,
props.startTaskDate,
props.isFavorite,
isAccessible,
props.onPressActionButton,
_.defaultTo(props.status, TaskStatus.Active),
() => swipableRef.current.close(),
@ -60,7 +78,7 @@ export const SwipableTaskCard: FC<IProps> = ({ onPress, ...props }) => { @@ -60,7 +78,7 @@ export const SwipableTaskCard: FC<IProps> = ({ onPress, ...props }) => {
btnsConfig.map(item => (
<SquareButton key={props.id + item.iconName} {...item} />
)),
[props.id, props.isFavorite],
[props.id, props.isFavorite, permissions, appTheme],
)
const onLongPress = btnsConfig[btnsConfig.length - 1].onPress

10
src/modules/tasks/smart-components/tasks-list-head.smart-component.tsx

@ -17,6 +17,9 @@ import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native' @@ -17,6 +17,9 @@ import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native'
import { ActionsForSelectedItemsRow } from '../components'
import { getSelectedTasksMenuOptions } from '../config'
import { useTaskActions } from '../hooks'
import { useSelector } from 'react-redux'
import { selectAccount } from '@/store/account'
import { selectPermissionsForUsers } from '@/store/permissions'
interface TasksListHeadSmartProps {
selectedTasks: ITaskDetails[]
@ -46,6 +49,9 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({ @@ -46,6 +49,9 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({
const navigation: any = useNavigation()
const { styles, theme } = useTheme(createStyles)
const account = useSelector(selectAccount)
const permissions = useSelector(selectPermissionsForUsers)
const goBack = () => {
simpleDispatch(new UnselectAllUsers())
simpleDispatch(new UnselectExecutor())
@ -58,6 +64,8 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({ @@ -58,6 +64,8 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({
const openMenu = () => {
const menuOptions = getSelectedTasksMenuOptions(
account,
permissions,
selectedTasks,
navigation.navigate,
{
@ -113,6 +121,8 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({ @@ -113,6 +121,8 @@ export const TasksListHeadSmart: FC<TasksListHeadSmartProps> = ({
}
tasks={selectedTasks}
taskIds={selectedTasks.map(it => it.id)}
user={account}
permissions={permissions}
dates={selectedTasks.map(it => it.startDate)}
onPressClear={onPressClear}
onPressRemove={handleDeleteTasks}

2
src/modules/tasks/smart-components/tasks-list.smart-component.tsx

@ -47,6 +47,8 @@ export const TasksListSmart = ({ @@ -47,6 +47,8 @@ export const TasksListSmart = ({
<SwipableTaskCard
key={index.toString()}
id={item.id}
authorId={item.authorId}
executorId={item.executor.id}
overdue={isOverdueCheck(item.endDate, item.status)}
isRead={item.isRead}
isFavorite={item.isFavorite}

1
src/services/system/real-time.service.ts

@ -101,6 +101,7 @@ export class SocketIo { @@ -101,6 +101,7 @@ export class SocketIo {
this._onSocketSendEvent('stopSessions')
this._onSocketSendEvent('push-notification')
this._onSocketSendEvent('version')
this._onSocketSendEvent('user/change-permissions')
this._on('error/join-user', async () => {
await authService.refreshSession()

3
src/shared/events/index.ts

@ -152,7 +152,7 @@ export type SocketEvents = { @@ -152,7 +152,7 @@ export type SocketEvents = {
'chat/unpin': { chatId: number }
'chat/unread': { chatId: number }
'task/new-comment': { taskId: number, commentId: number, userId: number }
'task/new-comment': { taskId: number; commentId: number; userId: number }
'task/update-comment': { comment: IComment }
'task/read-comments': { taskId: number; userId?: number }
'task/delete-comment': {
@ -181,6 +181,7 @@ export type SocketEvents = { @@ -181,6 +181,7 @@ export type SocketEvents = {
'user/disconnected': { userId: number; sessionType: string }
'user/deleted': { userId: number }
'user/new-user': { userId: number }
'user/change-permissions': any
'taxonomy/new': { id: number; type: TaxonomyTypes }
stopSessions: { sessionsIds: number[] }

2
src/shared/themes/dark/task-card.ts

@ -17,4 +17,6 @@ export const taskCardColors: TaskCardColors = { @@ -17,4 +17,6 @@ export const taskCardColors: TaskCardColors = {
$doneText: '#27771B',
$deleteBtn: '#E4B9B9',
$deleteText: '#870D0D',
$unAccessibleBtn: '#353535',
$unAccessibleTxt: '#1A1919',
}

4
src/shared/themes/interfaces/task-card.interface.ts

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
export interface TaskCardColors {
taskTitle : {
taskTitle: {
$primaryText: string
$secondaryText: string
}
@ -15,4 +15,6 @@ export interface TaskCardColors { @@ -15,4 +15,6 @@ export interface TaskCardColors {
$doneText: string
$deleteBtn: string
$deleteText: string
$unAccessibleBtn: string
$unAccessibleTxt: string
}

6
src/shared/themes/light/task-card.ts

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import { TaskCardColors } from '../interfaces/task-card.interface'
export const taskCardColors: TaskCardColors = {
taskTitle : {
taskTitle: {
$primaryText: '#3B3B3B',
$secondaryText: '#9E2743',
},
@ -9,7 +9,7 @@ export const taskCardColors: TaskCardColors = { @@ -9,7 +9,7 @@ export const taskCardColors: TaskCardColors = {
$indicatorBg: '#9E2743',
},
selectedItems: {
$selectedText: '#C6C6C6'
$selectedText: '#C6C6C6',
},
$pinBtn: '#FFDF6D',
$pinText: '#B78F00',
@ -17,4 +17,6 @@ export const taskCardColors: TaskCardColors = { @@ -17,4 +17,6 @@ export const taskCardColors: TaskCardColors = {
$doneText: '#27771B',
$deleteBtn: '#E4B9B9',
$deleteText: '#870D0D',
$unAccessibleBtn: '#D3D3D3',
$unAccessibleTxt: '#BDBCBC',
}

Loading…
Cancel
Save