Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8b79089

Browse files
Block editing if someone else is editing the app
1 parent8cae836 commit8b79089

File tree

6 files changed

+68
-15
lines changed

6 files changed

+68
-15
lines changed

‎client/packages/lowcoder/src/api/applicationApi.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
PublishApplicationPayload,
1010
RecycleApplicationPayload,
1111
RestoreApplicationPayload,
12+
SetAppEditingStatePayload,
1213
UpdateAppPermissionPayload,
1314
}from"redux/reduxActions/applicationActions";
1415
import{ApiResponse,GenericApiResponse}from"./apiResponses";
@@ -96,6 +97,7 @@ class ApplicationApi extends Api {
9697
staticpublicToAllURL=(applicationId:string)=>`/applications/${applicationId}/public-to-all`;
9798
staticpublicToMarketplaceURL=(applicationId:string)=>`/v1/applications/${applicationId}/public-to-marketplace`;
9899
staticgetMarketplaceAppURL=(applicationId:string)=>`/v1/applications/${applicationId}/view_marketplace`;
100+
staticsetAppEditingStateURL=(applicationId:string)=>`/v1/applications/editState/${applicationId}`;
99101

100102

101103
staticfetchHomeData(request:HomeDataPayload):AxiosPromise<HomeDataResponse>{
@@ -232,6 +234,13 @@ class ApplicationApi extends Api {
232234
staticgetMarketplaceApp(appId:string){
233235
returnApi.get(ApplicationApi.getMarketplaceAppURL(appId));
234236
}
237+
238+
staticsetAppEditingState(request:SetAppEditingStatePayload):AxiosPromise<ApplicationResp>{
239+
const{ applicationId, editingFinished}=request;
240+
returnApi.put(ApplicationApi.setAppEditingStateURL(applicationId),{
241+
editingFinished,
242+
});
243+
}
235244
}
236245

237246
exportdefaultApplicationApi;

‎client/packages/lowcoder/src/constants/applicationConstants.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export interface ApplicationMeta {
9191
folder:false;
9292
isLocalMarketplace?:boolean;
9393
applicationStatus:"NORMAL"|"RECYCLED"|"DELETED";
94+
editingUserId:string|null;
9495
}
9596

9697
exportinterfaceFolderMeta{

‎client/packages/lowcoder/src/constants/reduxActionConstants.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export const ReduxActionTypes = {
144144
FETCH_ALL_MODULES_SUCCESS:"FETCH_ALL_MODULES_SUCCESS",
145145
FETCH_ALL_MARKETPLACE_APPS:"FETCH_ALL_MARKETPLACE_APPS",
146146
FETCH_ALL_MARKETPLACE_APPS_SUCCESS:"FETCH_ALL_MARKETPLACE_APPS_SUCCESS",
147+
SET_APP_EDITING_STATE:"SET_APP_EDITING_STATE",
147148

148149
/* user profile */
149150
SET_USER_PROFILE_SETTING_MODAL_VISIBLE:"SET_USER_PROFILE_SETTING_MODAL_VISIBLE",

‎client/packages/lowcoder/src/pages/common/header.tsx‎

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
AUTH_LOGIN_URL,
1010
preview,
1111
}from"constants/routesURL";
12-
import{User}from"constants/userConstants";
12+
import{CurrentUser,User}from"constants/userConstants";
1313
import{
1414
CommonTextLabel,
1515
CustomModal,
@@ -56,6 +56,8 @@ import { EditorContext } from "../../comps/editorState";
5656
importTooltipfrom"antd/es/tooltip";
5757
import{LockOutlined,ExclamationCircleOutlined}from'@ant-design/icons';
5858
importAvatarfrom'antd/es/avatar';
59+
importUserApifrom"@lowcoder-ee/api/userApi";
60+
import{validateResponse}from"@lowcoder-ee/api/apiUtils";
5961

6062

6163
constStyledLink=styled.a`
@@ -343,12 +345,26 @@ export default function Header(props: HeaderProps) {
343345
const[editName,setEditName]=useState(false);
344346
const[editing,setEditing]=useState(false);
345347
const[permissionDialogVisible,setPermissionDialogVisible]=useState(false);
348+
const[editingUser,setEditingUser]=useState<CurrentUser>();
346349

347350
constisModule=appType===AppTypeEnum.Module;
351+
constblockEditing=useMemo(
352+
()=>user.id!==application?.editingUserId,
353+
[application?.editingUserId]
354+
);
348355

349-
// Raheel: Todo - get concurrent editing state by API
350-
// maybe via editorState.getConcurrentAppEditingState(); as a new function?
351-
const[concurrentAppEditingState,setConcurrentAppEditingState]=useState(true);
356+
useEffect(()=>{
357+
if(blockEditing&&application&&Boolean(application?.editingUserId)){
358+
UserApi.getUserDetail(application.editingUserId!)
359+
.then(resp=>{
360+
if(validateResponse(resp)){
361+
console.log(resp.data.data);
362+
setEditingUser(resp.data.data);
363+
}
364+
});
365+
}
366+
},[blockEditing]);
367+
console.log(user.id,application?.editingUserId);
352368

353369
consteditorModeOptions=[
354370
{
@@ -491,7 +507,7 @@ export default function Header(props: HeaderProps) {
491507
) :(
492508
<>
493509
{/* Display a hint about who is editing the app */}
494-
{concurrentAppEditingState&&(
510+
{blockEditing&&(
495511
<Tooltip
496512
title="Changes will not be saved while another user is editing this app."
497513
color="red"
@@ -500,7 +516,8 @@ export default function Header(props: HeaderProps) {
500516
<EditingNoticeWrapper>
501517
<Avatarsize="small"src={user.avatarUrl}/>
502518
<EditingHintText>
503-
{`${user.username} is currently editing this app.`}
519+
{/* {`${user.username} is currently editing this app.`} */}
520+
{`${editingUser?.name||'Someone'} is currently editing this app`}
504521
</EditingHintText>
505522
<WarningIcon/>
506523
</EditingNoticeWrapper>
@@ -534,7 +551,7 @@ export default function Header(props: HeaderProps) {
534551
<DropdownMenuStyled
535552
style={{minWidth:"110px",borderRadius:"4px"}}
536553
onClick={(e)=>{
537-
if(concurrentAppEditingState)return;// Prevent clicks if the app is being edited by someone else
554+
if(blockEditing)return;// Prevent clicks if the app is being edited by someone else
538555
if(e.key==="deploy"){
539556
dispatch(publishApplication({ applicationId}));
540557
}elseif(e.key==="snapshot"){
@@ -546,31 +563,31 @@ export default function Header(props: HeaderProps) {
546563
key:"deploy",
547564
label:(
548565
<divstyle={{display:'flex',alignItems:'center'}}>
549-
{concurrentAppEditingState&&<LockOutlinedstyle={{marginRight:'8px'}}/>}
550-
<CommonTextLabelstyle={{color:concurrentAppEditingState ?"#ccc" :"#222"}}>
566+
{blockEditing&&<LockOutlinedstyle={{marginRight:'8px'}}/>}
567+
<CommonTextLabelstyle={{color:blockEditing ?"#ccc" :"#222"}}>
551568
{trans("header.deploy")}
552569
</CommonTextLabel>
553570
</div>
554571
),
555-
disabled:concurrentAppEditingState,
572+
disabled:blockEditing,
556573
},
557574
{
558575
key:"snapshot",
559576
label:(
560577
<divstyle={{display:'flex',alignItems:'center'}}>
561-
{concurrentAppEditingState&&<LockOutlinedstyle={{marginRight:'8px'}}/>}
562-
<CommonTextLabelstyle={{color:concurrentAppEditingState ?"#ccc" :"#222"}}>
578+
{blockEditing&&<LockOutlinedstyle={{marginRight:'8px'}}/>}
579+
<CommonTextLabelstyle={{color:blockEditing ?"#ccc" :"#222"}}>
563580
{trans("header.snapshot")}
564581
</CommonTextLabel>
565582
</div>
566583
),
567-
disabled:concurrentAppEditingState,
584+
disabled:blockEditing,
568585
},
569586
]}
570587
/>
571588
)}
572589
>
573-
<PackUpBtnbuttonType="primary"disabled={concurrentAppEditingState}>
590+
<PackUpBtnbuttonType="primary"disabled={blockEditing}>
574591
<PackUpIcon/>
575592
</PackUpBtn>
576593
</Dropdown>
@@ -583,7 +600,8 @@ export default function Header(props: HeaderProps) {
583600
showAppSnapshot,
584601
applicationId,
585602
permissionDialogVisible,
586-
concurrentAppEditingState,// Include the state in the dependency array
603+
blockEditing,// Include the state in the dependency array
604+
editingUser?.name,
587605
]);
588606

589607
return(

‎client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ export type FetchAppInfoPayload = {
134134
onSuccess?:(info:AppSummaryInfo)=>void;
135135
onError?:(error:string)=>void;
136136
};
137+
138+
exporttypeSetAppEditingStatePayload={
139+
applicationId:string;
140+
editingFinished:boolean;
141+
};
142+
137143
exportconstfetchApplicationInfo=(payload:FetchAppInfoPayload)=>({
138144
type:ReduxActionTypes.FETCH_APPLICATION_DETAIL,
139145
payload:payload,
@@ -170,3 +176,8 @@ export const deleteAppPermission = (payload: DeleteAppPermissionPayload) => ({
170176
type:ReduxActionTypes.DELETE_APP_PERMISSION,
171177
payload:payload,
172178
});
179+
180+
exportconstsetAppEditingState=(payload:SetAppEditingStatePayload)=>({
181+
type:ReduxActionTypes.SET_APP_EDITING_STATE,
182+
payload:payload,
183+
});

‎client/packages/lowcoder/src/redux/sagas/applicationSagas.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
PublishApplicationPayload,
2323
RecycleApplicationPayload,
2424
RestoreApplicationPayload,
25+
SetAppEditingStatePayload,
2526
UpdateApplicationPayload,
2627
UpdateAppMetaPayload,
2728
UpdateAppPermissionPayload,
@@ -391,6 +392,17 @@ function* fetchAllMarketplaceAppsSaga() {
391392
}
392393
}
393394

395+
function*setAppEditingStateSaga(action:ReduxAction<SetAppEditingStatePayload>){
396+
try{
397+
yieldcall(
398+
ApplicationApi.setAppEditingState,
399+
action.payload
400+
);
401+
}catch(error){
402+
log.debug("set app editing state: ",error);
403+
}
404+
}
405+
394406
exportdefaultfunction*applicationSagas(){
395407
yieldall([
396408
takeLatest(ReduxActionTypes.FETCH_HOME_DATA,fetchHomeDataSaga),
@@ -416,5 +428,6 @@ export default function* applicationSagas() {
416428
ReduxActionTypes.FETCH_ALL_MARKETPLACE_APPS,
417429
fetchAllMarketplaceAppsSaga,
418430
),
431+
takeLatest(ReduxActionTypes.SET_APP_EDITING_STATE,setAppEditingStateSaga),
419432
]);
420433
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp