feat: Add board activity log

This commit is contained in:
Maksim Eltyshev
2025-05-22 23:14:46 +02:00
parent 777ff467f3
commit 86cfd155f2
72 changed files with 833 additions and 169 deletions

View File

@@ -7,14 +7,17 @@ import React from 'react';
import { useSelector } from 'react-redux';
import selectors from '../../../selectors';
import ModalTypes from '../../../constants/ModalTypes';
import { BoardContexts, BoardViews } from '../../../constants/Enums';
import KanbanContent from './KanbanContent';
import FiniteContent from './FiniteContent';
import EndlessContent from './EndlessContent';
import CardModal from '../../cards/CardModal';
import BoardActivitiesModal from '../../activities/BoardActivitiesModal';
const Board = React.memo(() => {
const board = useSelector(selectors.selectCurrentBoard);
const modal = useSelector(selectors.selectCurrentModal);
const isCardModalOpened = useSelector((state) => !!selectors.selectPath(state).cardId);
let Content;
@@ -35,10 +38,23 @@ const Board = React.memo(() => {
}
}
let modalNode = null;
if (isCardModalOpened) {
modalNode = <CardModal />;
} else if (modal) {
switch (modal.type) {
case ModalTypes.BOARD_ACTIVITIES:
modalNode = <BoardActivitiesModal />;
break;
default:
}
}
return (
<>
<Content />
{isCardModalOpened && <CardModal />}
{modalNode}
</>
);
});

View File

@@ -21,14 +21,14 @@ import CustomFieldGroupsStep from '../../../custom-field-groups/CustomFieldGroup
import styles from './ActionsStep.module.scss';
const StepTypes = {
EMPTY_TRASH: 'EMPTY_TRASH',
CUSTOM_FIELD_GROUPS: 'CUSTOM_FIELD_GROUPS',
EMPTY_TRASH: 'EMPTY_TRASH',
};
const ActionsStep = React.memo(({ onClose }) => {
const board = useSelector(selectors.selectCurrentBoard);
const { withSubscribe, withTrashEmptier, withCustomFieldGroups } = useSelector((state) => {
const { withSubscribe, withCustomFieldGroups, withTrashEmptier } = useSelector((state) => {
const isManager = selectors.selectIsCurrentUserManagerForCurrentProject(state);
const boardMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state);
@@ -42,8 +42,8 @@ const ActionsStep = React.memo(({ onClose }) => {
return {
withSubscribe: isMember, // TODO: rename?
withTrashEmptier: board.context === BoardContexts.TRASH && (isManager || isEditor),
withCustomFieldGroups: isEditor,
withTrashEmptier: board.context === BoardContexts.TRASH && (isManager || isEditor),
};
}, shallowEqual);
@@ -69,21 +69,28 @@ const ActionsStep = React.memo(({ onClose }) => {
[onClose, dispatch],
);
const handleActivitiesClick = useCallback(() => {
dispatch(entryActions.openBoardActivitiesModal());
onClose();
}, [onClose, dispatch]);
const handleEmptyTrashConfirm = useCallback(() => {
dispatch(entryActions.clearTrashListInCurrentBoard());
onClose();
}, [onClose, dispatch]);
const handleEmptyTrashClick = useCallback(() => {
openStep(StepTypes.EMPTY_TRASH);
}, [openStep]);
const handleCustomFieldsClick = useCallback(() => {
openStep(StepTypes.CUSTOM_FIELD_GROUPS);
}, [openStep]);
const handleEmptyTrashClick = useCallback(() => {
openStep(StepTypes.EMPTY_TRASH);
}, [openStep]);
if (step) {
switch (step.type) {
case StepTypes.CUSTOM_FIELD_GROUPS:
return <CustomFieldGroupsStep onBack={handleBack} onClose={onClose} />;
case StepTypes.EMPTY_TRASH:
return (
<ConfirmationStep
@@ -94,8 +101,6 @@ const ActionsStep = React.memo(({ onClose }) => {
onBack={handleBack}
/>
);
case StepTypes.CUSTOM_FIELD_GROUPS:
return <CustomFieldGroupsStep onBack={handleBack} onClose={onClose} />;
default:
}
}
@@ -128,6 +133,12 @@ const ActionsStep = React.memo(({ onClose }) => {
})}
</Menu.Item>
)}
<Menu.Item className={styles.menuItem} onClick={handleActivitiesClick}>
<Icon name="list ul" className={styles.menuItemIcon} />
{t('common.actions', {
context: 'title',
})}
</Menu.Item>
{withTrashEmptier && (
<>
{(withSubscribe || withCustomFieldGroups) && <hr className={styles.divider} />}