made activeuser component which can be used wherever and only use it if the user can save the file on the form and diagram edit pages

This commit is contained in:
jasquat 2023-05-05 09:52:52 -04:00
parent 863350bdb6
commit 7be5bf43fd
4 changed files with 134 additions and 96 deletions

View File

@ -0,0 +1,52 @@
import { useEffect, useState } from 'react';
import HttpService from '../services/HttpService';
import {
encodeBase64,
refreshAtInterval,
REFRESH_TIMEOUT_SECONDS,
} from '../helpers';
import { User } from '../interfaces';
export default function ActiveUsers() {
// Handles getting and displaying active users.
const [activeUsers, setActiveUsers] = useState<User[]>([]);
const lastVisitedIdentifier = encodeBase64(window.location.pathname);
useEffect(() => {
const updateActiveUsers = () => {
HttpService.makeCallToBackend({
path: `/active-users/updates/${lastVisitedIdentifier}`,
successCallback: setActiveUsers,
});
};
const unregisterUser = () => {
HttpService.makeCallToBackend({
path: `/active-users/unregister/${lastVisitedIdentifier}`,
successCallback: setActiveUsers,
});
};
updateActiveUsers();
return refreshAtInterval(
15,
REFRESH_TIMEOUT_SECONDS,
updateActiveUsers,
unregisterUser
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // it is critical to only run this once.
const au = activeUsers.map((activeUser: User) => {
return (
<div
title={`${activeUser.username} is also viewing this page`}
className="user-circle"
>
{activeUser.username.charAt(0).toUpperCase()}
</div>
);
});
return <div className="user-list">{au}</div>;
}

View File

@ -674,7 +674,14 @@ export default function ReactDiagramEditor({
)}
</Can>
{getReferencesButton()}
{/* only show other users if the current user can save the current diagram */}
<Can
I="PUT"
a={targetUris.processModelFileShowPath}
ability={ability}
>
{activeUserElement || null}
</Can>
</ButtonSet>
);
}

View File

@ -29,24 +29,18 @@ import HttpService from '../services/HttpService';
import ReactDiagramEditor from '../components/ReactDiagramEditor';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import useAPIError from '../hooks/UseApiError';
import {
makeid,
modifyProcessIdentifierForPathParam,
encodeBase64,
refreshAtInterval,
REFRESH_TIMEOUT_SECONDS,
} from '../helpers';
import { makeid, modifyProcessIdentifierForPathParam } from '../helpers';
import {
CarbonComboBoxProcessSelection,
ProcessFile,
ProcessModel,
ProcessModelCaller,
ProcessReference,
User,
} from '../interfaces';
import ProcessSearch from '../components/ProcessSearch';
import { Notification } from '../components/Notification';
import { usePrompt } from '../hooks/UsePrompt';
import ActiveUsers from '../components/ActiveUsers';
export default function ProcessModelEditDiagram() {
const [showFileNameEditor, setShowFileNameEditor] = useState(false);
@ -73,7 +67,6 @@ export default function ProcessModelEditDiagram() {
useState<boolean>(false);
const [processModelFileInvalidText, setProcessModelFileInvalidText] =
useState<string>('');
const [activeUsers, setActiveUsers] = useState<User[]>([]);
const handleShowMarkdownEditor = () => setShowMarkdownEditor(true);
@ -132,14 +125,7 @@ export default function ProcessModelEditDiagram() {
usePrompt('Changes you made may not be saved.', diagramHasChanges);
const lastVisitedIdentifier = encodeBase64(window.location.pathname);
useEffect(() => {
const updateActiveUsers = () => {
HttpService.makeCallToBackend({
path: `/active-users/updates/${lastVisitedIdentifier}`,
successCallback: setActiveUsers,
});
};
// Grab all available process models in case we need to search for them.
// Taken from the Process Group List
const processResults = (result: any) => {
@ -154,21 +140,6 @@ export default function ProcessModelEditDiagram() {
path: `/processes`,
successCallback: processResults,
});
const unregisterUser = () => {
HttpService.makeCallToBackend({
path: `/active-users/unregister/${lastVisitedIdentifier}`,
successCallback: setActiveUsers,
});
};
updateActiveUsers();
return refreshAtInterval(
15,
REFRESH_TIMEOUT_SECONDS,
updateActiveUsers,
unregisterUser
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // it is critical to only run this once.
@ -959,20 +930,6 @@ export default function ProcessModelEditDiagram() {
return searchParams.get('file_type') === 'dmn' || fileName.endsWith('.dmn');
};
const activeUserElement = () => {
const au = activeUsers.map((activeUser: User) => {
return (
<div
title={`${activeUser.username} is also viewing this page`}
className="user-circle"
>
{activeUser.username.charAt(0).toUpperCase()}
</div>
);
});
return <div className="user-list">{au}</div>;
};
const appropriateEditor = () => {
if (isDmn()) {
return (
@ -1017,7 +974,7 @@ export default function ProcessModelEditDiagram() {
onSearchProcessModels={onSearchProcessModels}
onElementsChanged={onElementsChanged}
callers={callers}
activeUserElement={activeUserElement()}
activeUserElement={<ActiveUsers />}
/>
);
};

View File

@ -4,7 +4,7 @@ import { useEffect, useState } from 'react';
import Editor from '@monaco-editor/react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
// @ts-ignore
import { Button, Modal } from '@carbon/react';
import { Button, ButtonSet, Modal } from '@carbon/react';
import { Can } from '@casl/react';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import HttpService from '../services/HttpService';
@ -15,6 +15,7 @@ import { Notification } from '../components/Notification';
import useAPIError from '../hooks/UseApiError';
import { usePermissionFetcher } from '../hooks/PermissionService';
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import ActiveUsers from '../components/ActiveUsers';
// NOTE: This is mostly the same as ProcessModelEditDiagram and if we go this route could
// possibly be merged into it. I'm leaving as a separate file now in case it does
// end up diverging greatly
@ -231,7 +232,12 @@ export default function ReactFormEditor() {
{newFileNameBox()}
{saveFileMessage()}
<Can I="PUT" a={targetUris.processModelFileShowPath} ability={ability}>
<ButtonSet>
<Can
I="PUT"
a={targetUris.processModelFileShowPath}
ability={ability}
>
<Button
onClick={saveFile}
variant="danger"
@ -254,7 +260,11 @@ export default function ReactFormEditor() {
/>
) : null}
</Can>
<Can I="PUT" a={targetUris.processModelFileShowPath} ability={ability}>
<Can
I="PUT"
a={targetUris.processModelFileShowPath}
ability={ability}
>
{hasFormBuilder ? (
<Button
onClick={() =>
@ -269,7 +279,11 @@ export default function ReactFormEditor() {
</Button>
) : null}
</Can>
<Can I="GET" a={targetUris.processModelFileShowPath} ability={ability}>
<Can
I="GET"
a={targetUris.processModelFileShowPath}
ability={ability}
>
{hasDiagram ? (
<Button
onClick={() =>
@ -284,6 +298,14 @@ export default function ReactFormEditor() {
</Button>
) : null}
</Can>
<Can
I="PUT"
a={targetUris.processModelFileShowPath}
ability={ability}
>
<ActiveUsers />
</Can>
</ButtonSet>
<Editor
height={600}
width="auto"