Got it!
Here's what I now have...
-
I have a Retool database table xxxx_user_login_tracker
:
-
I have a js query set_user_and_datetime
that automatically runs ever 60 seconds that captures the data and triggers the update query:
-
I have the update query SAVE_this_user_login
:
-
I have the GET query GET_user_logins
:
-
And the get transformer get_users_logged_in
:
-
I have a fancy checkUsersButton
button that changes words and colors depending on if someone else is logged in:
-
And I have a modal that comes up when you click the checkUsersButton
:
Thank you, @ferret141, for the idea!
~Bon
And if you want to copy and paste the long bits of code, here they are:
set_user_and_datetime
var user_email = current_user.email;
var user_name = current_user.fullName;
const date = new Date();
const formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/New_York'
});
const formattedTime = date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
timeZone: 'America/New_York',
timeZoneName: 'short'
});
SAVE_this_user_login.trigger({
additionalScope: {
userEmail: user_email,
userName: user_name,
recentActivity: date,
recentActivityDate: formattedDate,
recentActivityTime: formattedTime
}
});
GET_user_logins.trigger();
return {"user_email": user_email,
"user_name": user_name,
"recent_activity": date,
"recent_activity_date": formattedDate,
"recent_activity_time": formattedTime};
SAVE_this_user_login
INSERT INTO xxxx_user_login_tracker (
user_email,
user_name,
recent_activity,
recent_activity_date,
recent_activity_time
)
VALUES (
{{ userEmail }},
{{ userName }},
{{ recentActivity }},
{{ recentActivityDate }},
{{ recentActivityTime }}
)
ON CONFLICT(user_email) DO UPDATE
SET user_name = EXCLUDED.user_name,
recent_activity = EXCLUDED.recent_activity,
recent_activity_date = EXCLUDED.recent_activity_date,
recent_activity_time = EXCLUDED.recent_activity_time
get_users_logged_in
const USER_LOGIN_DATA = {{ formatDataAsArray(GET_user_logins.data) }};
const NOW = new Date();
const ONE_MIN_BEFORE_NOW = new Date(NOW.getTime() - (1 * 60 * 1000));
const formatted_one_min_before_date = ONE_MIN_BEFORE_NOW.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/New_York'
});
const formatted_one_min_before_time = ONE_MIN_BEFORE_NOW.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
timeZone: 'America/New_York',
timeZoneName: 'short'
});
const recent_logins = USER_LOGIN_DATA.map(one_user => {
const RECENT_ACTIVITY_DATE = one_user.recent_activity_date;
const RECENT_ACIVITY_TIME = one_user.recent_activity_time;
const RECENT_ACTIVITY = new Date(one_user.recent_activity)
return {
...one_user,
other_user_recently_logged_in: (RECENT_ACTIVITY_DATE == formatted_one_min_before_date) && (RECENT_ACIVITY_TIME > formatted_one_min_before_time) && one_user.user_email !== {{ current_user.email }} ,
minutes_since_last_checkin: Math.abs(NOW.getTime() - RECENT_ACTIVITY.getTime()) / 60000
};
});
let sorted_logins = recent_logins.sort((a, b) => a.minutes_since_last_checkin - b.minutes_since_last_checkin);
const LOGIN_WARNING = sorted_logins.some(user => user.other_user_recently_logged_in);
return {
recent_logins: sorted_logins,
LOGIN_WARNING: LOGIN_WARNING
};
DISCLAIMER: I'm a python developer by nature, so I'm not so great with javascript. Feel free to make suggestions to improve my javascript - but don't make fun of me.