Skip to content

Commit

Permalink
HistoryEntry.jsx: diffSummary, edit user comment only displayed if av…
Browse files Browse the repository at this point in the history
…ailable.
  • Loading branch information
kreinhard committed Feb 16, 2025
1 parent 94ec53f commit f026175
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,4 @@ package org.projectforge.framework.persistence.entities
* Please refer UserPagesRest as an example.
* @see org.projectforge.framework.persistence.history.HistoryEntryDO.userComment
*/
interface HistoryUserCommentSupport {
}
interface HistoryUserCommentSupport
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@

package org.projectforge.framework.persistence.history

import com.fasterxml.jackson.annotation.JsonProperty
import org.projectforge.framework.i18n.TimeAgo
import org.projectforge.framework.i18n.translate
import java.util.*

class DisplayHistoryEntry {
class DiffCount(val type: EntityOpType, val count: Int, val operation: String)

/**
* The id of the history entry (pk of database).
*/
Expand All @@ -43,6 +47,42 @@ class DisplayHistoryEntry {
val operation: String
get() = HistoryFormatService.translate(operationType)
var userComment: String? = null
@Suppress("unused") // Used by React frontend.
@get:JsonProperty
val diffSummary: List<DiffCount>
get() {
var inserted = 0
var updated = 0
var deleted = 0
attributes.forEach { attr ->
when (attr.operationType) {
PropertyOpType.Insert -> inserted++
PropertyOpType.Update -> updated++
PropertyOpType.Delete -> deleted++
else -> {}
}
}
if (inserted == 0 && updated == 0 && deleted == 0) {
when (operationType) {
EntityOpType.Insert -> inserted++
EntityOpType.Update -> updated++
EntityOpType.Delete -> deleted++
else -> {}
}
}
val actions = mutableListOf<DiffCount>()
if (inserted > 0) {
actions.add(DiffCount(EntityOpType.Insert, inserted, translate("operation.inserted")))
}
if (updated > 0) {
actions.add(DiffCount(EntityOpType.Update, updated, translate("operation.updated")))
}
if (deleted > 0) {
actions.add(DiffCount(EntityOpType.Delete, deleted, translate("operation.deleted")))
}
return actions
}

var attributes = mutableListOf<DisplayHistoryEntryAttr>()

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ constructor(
newBaseDTO(request)
})
?: return ResponseEntity(HttpStatus.NOT_FOUND)
userAccess.editHistoryComments = baseDao.supportsHistoryUserComments
onBeforeGetItemAndLayout(request, item, userAccess)
val formLayoutData = getItemAndLayout(request, item, userAccess)
returnToCaller?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ class UILayout(
* The user has access to the object's history, if given.
*/
var history: Boolean? = null,
/**
* Is the edit user-comment button visible?
* @see [org.projectforge.framework.persistence.api.BaseDao.supportsHistoryUserComments]
*/
var editHistoryComments: Boolean? = null,
/**
* The user has access to insert new objects.
*/
Expand All @@ -56,6 +61,7 @@ class UILayout(
this.update = userAccess?.update
this.delete = userAccess?.delete
this.cancel = userAccess?.cancel ?: true
this.editHistoryComments = userAccess?.editHistoryComments
}

fun onlySelectAccess(): Boolean {
Expand Down
2 changes: 2 additions & 0 deletions projectforge-webapp/src/containers/page/form/FormPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function FormPage(
} = category;
const location = useLocation();
const [searchParams] = useSearchParams();
const { userAccess } = ui || {};

React.useEffect(
() => {
Expand Down Expand Up @@ -164,6 +165,7 @@ function FormPage(
id={id}
translations={ui.translations}
visible={tab === 'history'}
userAccess={userAccess}
/>
</Container>
</TabPane>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ function HistoryEntry(
timeAgo,
modifiedAt,
modifiedByUser,
diffSummary,
},
userAccess,
translations,
},
) {
const [active, setActive] = React.useState(false);
const diffSummary = {};

const callAction = useActions(callActionHandler);

Expand All @@ -50,24 +51,13 @@ function HistoryEntry(
},
}), [callAction, masterId]);

attributes.forEach(({ operation, operationType }) => {
let diff = diffSummary[operationType];

if (!diff) {
diff = {
operation,
amount: 1,
};
} else {
diff.amount += 1;
}

diffSummary[operationType] = diff;
});

const idifiedDate = String.idify(modifiedAt);
const dateId = `history-date-${idifiedDate}`;

const { editHistoryComments } = userAccess;

console.log(userAccess);

return (
<div
className={classNames(style.entry, { [style.active]: active })}
Expand All @@ -83,13 +73,13 @@ function HistoryEntry(
</Col>
<Col>
<span className={style.changesAmount}>
{Object.keys(diffSummary)
.map((diffType) => (
{diffSummary
.map((diff) => (
<span
className={style[diffType]}
className={style[diff.type]}
key={`history-diff-summary-${masterId}`}
>
{`${diffSummary[diffType].amount} ${diffSummary[diffType].operation}`}
{`${diff.count} ${diff.operation}`}
</span>
))}
</span>
Expand Down Expand Up @@ -120,14 +110,16 @@ function HistoryEntry(
{userComment && (
<pre className={style.comment}>{userComment}</pre>
)}
<Button
type="button"
color="link"
className={style.editComment}
onClick={editComment}
>
{getTranslation('history.userComment.edit', translations)}
</Button>
{editHistoryComments && (
<Button
type="button"
color="link"
className={style.editComment}
onClick={editComment}
>
{getTranslation('history.userComment.edit', translations)}
</Button>
)}
<h5>
<strong>
{getTranslation('changes', translations)}
Expand All @@ -136,15 +128,15 @@ function HistoryEntry(
</h5>
{attributes.map((
{
operationType,
operationType: attrOperationType,
displayPropertyName,
oldValue,
newValue,
},
) => {
let diff;

switch (operationType) {
switch (attrOperationType) {
case 'Insert':
diff = `${newValue}`;
break;
Expand All @@ -168,8 +160,8 @@ function HistoryEntry(
key={`history-diff-${masterId}`}
className={style.detail}
>
<span className={style[operationType]}>
{getTypeSymbol(operationType)}
<span className={style[attrOperationType]}>
{getTypeSymbol(attrOperationType)}
{' '}
{displayPropertyName}
{': '}
Expand Down Expand Up @@ -197,12 +189,18 @@ HistoryEntry.propTypes = {
id: PropTypes.number,
modifiedAt: PropTypes.string,
modifiedByUser: PropTypes.string,
diffSummary: PropTypes.arrayOf(PropTypes.shape({
type: PropTypes.string,
count: PropTypes.number,
operation: PropTypes.string,
})),
userComment: PropTypes.string,
modifiedByUserId: PropTypes.number,
operation: PropTypes.string,
operationType: PropTypes.string,
timeAgo: PropTypes.string,
}).isRequired,
userAccess: PropTypes.shape({
editHistoryComments: PropTypes.bool,
}),
translations: PropTypes.shape({
changes: PropTypes.string,
history: PropTypes.arrayOf(PropTypes.shape({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function FormHistory({
id,
visible = false,
translations,
userAccess,
}) {
const [loading, setLoading] = useState(true);
const [history, setHistory] = useState([]);
Expand Down Expand Up @@ -62,6 +63,7 @@ function FormHistory({
key={`history-entry-at-${entry.modifiedAt}`}
entry={entry}
translations={translations}
userAccess={userAccess}
/>
))}
</LoadingContainer>
Expand All @@ -75,6 +77,9 @@ FormHistory.propTypes = {
translations: PropTypes.shape({
changes: PropTypes.string,
}),
userAccess: PropTypes.shape({
editHistoryComments: PropTypes.bool,
}),
};

export default FormHistory;

0 comments on commit f026175

Please sign in to comment.