feat: [Feature] Added release version api for clients and RTS (#8324)
Added a new event in RTS when new version is deployed. After receiving this event, client will show a prompt to refresh.
This commit is contained in:
parent
b951d8db21
commit
09eff23479
1
.github/workflows/github-release.yml
vendored
1
.github/workflows/github-release.yml
vendored
|
|
@ -168,6 +168,7 @@ jobs:
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
echo 'export const VERSION = "${{ needs.prelude.outputs.tag }}"' > src/version.js
|
||||||
./build.sh
|
./build.sh
|
||||||
ls -l dist
|
ls -l dist
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,7 @@ jobs:
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
echo 'export const VERSION = "${{ steps.vars.outputs.version }}"' > src/version.js
|
||||||
./build.sh
|
./build.sh
|
||||||
ls -l dist
|
ls -l dist
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ const StyledDebugButton = styled(DebugButton)`
|
||||||
|
|
||||||
const StyledActionText = styled(Text)`
|
const StyledActionText = styled(Text)`
|
||||||
color: ${(props) => props.theme.colors.toast.undoRedoColor} !important;
|
color: ${(props) => props.theme.colors.toast.undoRedoColor} !important;
|
||||||
|
cursor: pointer;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function ToastComponent(
|
export function ToastComponent(
|
||||||
|
|
|
||||||
|
|
@ -804,6 +804,8 @@ export const RESTART_BANNER_HEADER = () => "Restarting Server";
|
||||||
export const RESTART_ERROR_BODY = () =>
|
export const RESTART_ERROR_BODY = () =>
|
||||||
"Something went wrong. Please contact your administrator.";
|
"Something went wrong. Please contact your administrator.";
|
||||||
export const RESTART_ERROR_HEADER = () => "Restart failed";
|
export const RESTART_ERROR_HEADER = () => "Restart failed";
|
||||||
|
export const INFO_VERSION_MISMATCH_FOUND_RELOAD_REQUEST = () =>
|
||||||
|
"Hey! There is a new version of Appsmith available. Please consider refreshing your window.";
|
||||||
|
|
||||||
export const WELCOME_FORM_NON_SUPER_USER_ROLE_DROPDOWN = () =>
|
export const WELCOME_FORM_NON_SUPER_USER_ROLE_DROPDOWN = () =>
|
||||||
"Tell us more about what you do at work?";
|
"Tell us more about what you do at work?";
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,14 @@ import {
|
||||||
import { collabSetAppEditors } from "actions/appCollabActions";
|
import { collabSetAppEditors } from "actions/appCollabActions";
|
||||||
import { newNotificationEvent } from "actions/notificationActions";
|
import { newNotificationEvent } from "actions/notificationActions";
|
||||||
import { getCurrentUser } from "selectors/usersSelectors";
|
import { getCurrentUser } from "selectors/usersSelectors";
|
||||||
|
import { Toaster } from "components/ads/Toast";
|
||||||
|
import {
|
||||||
|
createMessage,
|
||||||
|
INFO_VERSION_MISMATCH_FOUND_RELOAD_REQUEST,
|
||||||
|
} from "constants/messages";
|
||||||
|
import { Variant } from "components/ads/common";
|
||||||
|
import React from "react";
|
||||||
|
import { getAppsmithConfigs } from "../../configs";
|
||||||
|
|
||||||
export default function* handleAppLevelSocketEvents(event: any) {
|
export default function* handleAppLevelSocketEvents(event: any) {
|
||||||
const currentUser = yield select(getCurrentUser);
|
const currentUser = yield select(getCurrentUser);
|
||||||
|
|
@ -75,5 +83,20 @@ export default function* handleAppLevelSocketEvents(event: any) {
|
||||||
yield put(collabSetAppEditors(event.payload[0]));
|
yield put(collabSetAppEditors(event.payload[0]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// notification on release version
|
||||||
|
case APP_LEVEL_SOCKET_EVENTS.RELEASE_VERSION_NOTIFICATION: {
|
||||||
|
const { appVersion } = getAppsmithConfigs();
|
||||||
|
if (appVersion.id != event.payload[0]) {
|
||||||
|
Toaster.show({
|
||||||
|
text: createMessage(INFO_VERSION_MISMATCH_FOUND_RELOAD_REQUEST),
|
||||||
|
variant: Variant.info,
|
||||||
|
actionElement: (
|
||||||
|
<span onClick={() => location.reload(true)}>REFRESH</span>
|
||||||
|
),
|
||||||
|
autoClose: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,6 +18,8 @@ export const APP_LEVEL_SOCKET_EVENTS = {
|
||||||
INSERT_NOTIFICATION: "insert:notification",
|
INSERT_NOTIFICATION: "insert:notification",
|
||||||
|
|
||||||
LIST_ONLINE_APP_EDITORS: "collab:online_editors", // user presence
|
LIST_ONLINE_APP_EDITORS: "collab:online_editors", // user presence
|
||||||
|
|
||||||
|
RELEASE_VERSION_NOTIFICATION: "info:release_version", // release version
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PAGE_LEVEL_SOCKET_EVENTS = {
|
export const PAGE_LEVEL_SOCKET_EVENTS = {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ import type mongodb from "mongodb"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import { LogLevelDesc } from "loglevel";
|
import { LogLevelDesc } from "loglevel";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
import { AppUser, CurrentEditorsEvent, Policy, Comment, CommentThread, MousePointerEvent } from "./models"
|
import { AppUser, CurrentEditorsEvent, Policy, Comment, CommentThread, MousePointerEvent } from "./models"
|
||||||
|
import { VERSION as buildVersion } from "./version" // release version of the api
|
||||||
|
|
||||||
const RTS_BASE_PATH = "/rts"
|
const RTS_BASE_PATH = "/rts"
|
||||||
|
|
||||||
|
|
@ -20,6 +22,7 @@ const EDITORS_EVENT_NAME : string = "collab:online_editors"
|
||||||
const START_EDIT_EVENT_NAME : string = "collab:start_edit"
|
const START_EDIT_EVENT_NAME : string = "collab:start_edit"
|
||||||
const LEAVE_EDIT_EVENT_NAME : string = "collab:leave_edit"
|
const LEAVE_EDIT_EVENT_NAME : string = "collab:leave_edit"
|
||||||
const MOUSE_POINTER_EVENT_NAME : string = "collab:mouse_pointer"
|
const MOUSE_POINTER_EVENT_NAME : string = "collab:mouse_pointer"
|
||||||
|
const RELEASE_VERSION_EVENT_NAME : string = "info:release_version"
|
||||||
|
|
||||||
// Setting the logLevel for all log messages
|
// Setting the logLevel for all log messages
|
||||||
const logLevel : LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL || "debug") as LogLevelDesc
|
const logLevel : LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL || "debug") as LogLevelDesc
|
||||||
|
|
@ -59,6 +62,7 @@ function main() {
|
||||||
})
|
})
|
||||||
|
|
||||||
io.on("connection", (socket: Socket) => {
|
io.on("connection", (socket: Socket) => {
|
||||||
|
socket.emit(RELEASE_VERSION_EVENT_NAME, buildVersion)
|
||||||
subscribeToEditEvents(socket, APP_ROOM_PREFIX)
|
subscribeToEditEvents(socket, APP_ROOM_PREFIX)
|
||||||
onAppSocketConnected(socket)
|
onAppSocketConnected(socket)
|
||||||
.catch((error) => log.error("Error in socket connected handler", error))
|
.catch((error) => log.error("Error in socket connected handler", error))
|
||||||
|
|
@ -71,39 +75,46 @@ function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
io.of(ROOT_NAMESPACE).adapter.on("leave-room", (room, id) => {
|
io.of(ROOT_NAMESPACE).adapter.on("leave-room", (room, id) => {
|
||||||
|
if(room.startsWith(APP_ROOM_PREFIX)) {
|
||||||
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} left the room ${room}`)
|
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} left the room ${room}`)
|
||||||
|
}
|
||||||
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
|
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
|
||||||
});
|
});
|
||||||
|
|
||||||
io.of(ROOT_NAMESPACE).adapter.on("join-room", (room, id) => {
|
io.of(ROOT_NAMESPACE).adapter.on("join-room", (room, id) => {
|
||||||
|
if(room.startsWith(APP_ROOM_PREFIX)) {
|
||||||
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} joined the room ${room}`)
|
log.debug(`ns:${ROOT_NAMESPACE}# socket ${id} joined the room ${room}`)
|
||||||
|
}
|
||||||
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
|
sendCurrentUsers(io, room, APP_ROOM_PREFIX);
|
||||||
});
|
});
|
||||||
|
|
||||||
io.of(PAGE_EDIT_NAMESPACE).adapter.on("leave-room", (room, id) => {
|
io.of(PAGE_EDIT_NAMESPACE).adapter.on("leave-room", (room, id) => {
|
||||||
log.debug(`ns:${PAGE_EDIT_NAMESPACE}# socket ${id} left the room ${room}`)
|
|
||||||
if(room.startsWith(PAGE_ROOM_PREFIX)) { // someone left the page edit, notify others
|
if(room.startsWith(PAGE_ROOM_PREFIX)) { // someone left the page edit, notify others
|
||||||
|
log.debug(`ns:${PAGE_EDIT_NAMESPACE} # socket ${id} left the room ${room}`)
|
||||||
io.of(PAGE_EDIT_NAMESPACE).to(room).emit(LEAVE_EDIT_EVENT_NAME, id);
|
io.of(PAGE_EDIT_NAMESPACE).to(room).emit(LEAVE_EDIT_EVENT_NAME, id);
|
||||||
}
|
}
|
||||||
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
|
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
|
||||||
});
|
});
|
||||||
|
|
||||||
io.of(PAGE_EDIT_NAMESPACE).adapter.on("join-room", (room, id) => {
|
io.of(PAGE_EDIT_NAMESPACE).adapter.on("join-room", (room, id) => {
|
||||||
|
if(room.startsWith(PAGE_ROOM_PREFIX)) {
|
||||||
log.debug(`ns:${PAGE_EDIT_NAMESPACE}# socket ${id} joined the room ${room}`)
|
log.debug(`ns:${PAGE_EDIT_NAMESPACE}# socket ${id} joined the room ${room}`)
|
||||||
|
}
|
||||||
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
|
sendCurrentUsers(io.of(PAGE_EDIT_NAMESPACE), room, PAGE_ROOM_PREFIX);
|
||||||
});
|
});
|
||||||
|
|
||||||
watchMongoDB(io)
|
|
||||||
.catch((error) => log.error("Error watching MongoDB", error))
|
|
||||||
|
|
||||||
app.use(express.static(path.join(__dirname, "static")))
|
app.use(express.static(path.join(__dirname, "static")))
|
||||||
|
|
||||||
|
watchMongoDB(io).catch((error) => log.error("Error watching MongoDB", error))
|
||||||
|
|
||||||
|
// run the server
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
log.info(`RTS running at http://localhost:${port}`)
|
log.info(`RTS version ${buildVersion} running at http://localhost:${port}`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function joinEditRoom(socket:Socket, roomId:string, roomPrefix:string) {
|
function joinEditRoom(socket:Socket, roomId:string, roomPrefix:string) {
|
||||||
// remove this socket from any other app rooms
|
// remove this socket from any other rooms with roomPrefix
|
||||||
if(socket.rooms) {
|
if(socket.rooms) {
|
||||||
socket.rooms.forEach(roomName => {
|
socket.rooms.forEach(roomName => {
|
||||||
if(roomName.startsWith(roomPrefix)) {
|
if(roomName.startsWith(roomPrefix)) {
|
||||||
|
|
|
||||||
1
app/rts/src/version.js
Normal file
1
app/rts/src/version.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export const VERSION = 'SNAPSHOT'
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "dist"
|
"outDir": "dist",
|
||||||
|
"allowJs": true
|
||||||
},
|
},
|
||||||
"lib": ["es2015"]
|
"lib": ["es2015"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user