Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: workspaces #1156

Merged
merged 95 commits into from
Dec 14, 2024
Merged
Changes from 1 commit
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
55dd355
feat: doctypes for workspaces
nikkothari22 Oct 22, 2024
111bb67
perf: cache channel members
nikkothari22 Nov 8, 2024
2a22cb5
perf: use cache for channel membership
nikkothari22 Nov 8, 2024
d2bdf60
perf: use cache for peer user ID
nikkothari22 Nov 8, 2024
d50df57
perf: do not invalidate channel cache on message send
nikkothari22 Nov 8, 2024
ba64b5d
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 12, 2024
0803df7
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 14, 2024
6f1cb12
fix: ignore user permissions when adding system messages
nikkothari22 Nov 16, 2024
60485ff
fix: channel members cache
nikkothari22 Nov 16, 2024
dec775a
fix: delete reactions when channel is deleted #1151
nikkothari22 Nov 16, 2024
9330ee5
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 16, 2024
3c57906
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 17, 2024
7cfc9ac
wip(ui): workspaces sidebar
nikkothari22 Nov 17, 2024
732fa7e
chore: add is_dm_thread for threads in DM channels
nikkothari22 Nov 17, 2024
bc6acd5
chore: patches for workspaces
nikkothari22 Nov 17, 2024
8f6edc3
fix:(tests): chat stream test with workspaces
nikkothari22 Nov 17, 2024
8c2f040
chore: linting
nikkothari22 Nov 17, 2024
9e27bed
chore(linting): convert SQL query to query builder
nikkothari22 Nov 17, 2024
85fe554
fix: do not auto-assign workspace to channel if DM thread
nikkothari22 Nov 17, 2024
13a2ffc
fix(tests): do not create channel member for chat stream test
nikkothari22 Nov 17, 2024
72899d8
fix: mutate members when creating a channel
nikkothari22 Nov 22, 2024
3d5a19e
fix: link preview spacing and height
nikkothari22 Nov 22, 2024
0f60418
chore: remove unused imports
nikkothari22 Nov 22, 2024
c47e302
perf: installed millionjs
nikkothari22 Nov 22, 2024
bab1226
perf: memoize DateTooltip
nikkothari22 Nov 22, 2024
2e73226
perf: reduce rerenders in ChatBoxBody
nikkothari22 Nov 22, 2024
27ceaff
Merge pull request #1162 from The-Commit-Company/fix-perf
nikkothari22 Nov 22, 2024
858424b
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 22, 2024
76a3802
fix: remove MillionLint
nikkothari22 Nov 26, 2024
5640c6b
chore: update packages
nikkothari22 Nov 26, 2024
d5597e2
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 27, 2024
cb78648
fix: delete thread channel if message is deleted
nikkothari22 Nov 29, 2024
09daa80
fix: do not allow non-admins to change channel name and description
nikkothari22 Nov 29, 2024
c4d56e0
chore: remove unused variable
nikkothari22 Nov 29, 2024
3565119
feat: updated permission checks with tests
nikkothari22 Nov 29, 2024
0791204
fix: revert yarn.lock
nikkothari22 Nov 29, 2024
3eb38b9
Merge branch 'develop' into raven-orgs
nikkothari22 Nov 29, 2024
0666d34
chore: linting
nikkothari22 Nov 29, 2024
0a6c7e2
feat: fetch workspaces for user
nikkothari22 Nov 29, 2024
c4e5d78
fix: perm check for joining threads
nikkothari22 Dec 6, 2024
a7e9fb9
fix: poll vote perm check
nikkothari22 Dec 6, 2024
3ae3f6c
fix: login page error banner
nikkothari22 Dec 6, 2024
98efebc
feat: add toggle theme in command menu
nikkothari22 Dec 6, 2024
2d836e4
fix: do not retry doctype preview on error
nikkothari22 Dec 6, 2024
40a6b4a
feat: show workspace name in command menu
nikkothari22 Dec 6, 2024
ca81367
feat: only fetch channels if user is part of workspace
nikkothari22 Dec 6, 2024
615bc2b
feat: show workspace in forward message
nikkothari22 Dec 6, 2024
9d83393
feat: show workspace in channel dropdown
nikkothari22 Dec 6, 2024
28c3afd
fix: always show create channel button
nikkothari22 Dec 6, 2024
bc0d826
chore: update packages
nikkothari22 Dec 6, 2024
341b6e8
fix: use random hash for DM channel IDs
nikkothari22 Dec 6, 2024
3f4f16b
fix: fetch DM channels
nikkothari22 Dec 6, 2024
ea9b543
fix: perm check for thread DMs
nikkothari22 Dec 6, 2024
3d4b18f
fix(test): removed unneccessary assertion
nikkothari22 Dec 6, 2024
e8ce5cf
fix: poll creation API type
nikkothari22 Dec 6, 2024
e9ef0f9
feat: workspace switcher
nikkothari22 Dec 6, 2024
f993a66
fix: users can only mention channels in the given workspace
nikkothari22 Dec 6, 2024
2af77a0
feat: thread and saved messages respect workspace
nikkothari22 Dec 6, 2024
531bfca
feat: join workspaces from switcher
nikkothari22 Dec 6, 2024
cec204e
chore: make a default workspace on install
nikkothari22 Dec 6, 2024
65d0a4b
fix: do not reroute if only one workspace
nikkothari22 Dec 6, 2024
a0287fe
fix: route using effect
nikkothari22 Dec 6, 2024
b938048
fix: do not route if only one workspace
nikkothari22 Dec 6, 2024
fb3cab0
fix: "try" adding all users to default workspace on install
nikkothari22 Dec 6, 2024
4ae8a05
feat: show unread counts on workspaces
nikkothari22 Dec 6, 2024
2f80f9a
fix: only fetch unread counts for members
nikkothari22 Dec 6, 2024
2d67382
fix: show workspace switcher grid on index
nikkothari22 Dec 6, 2024
361d1d7
fix: update user cache when updating status and image
nikkothari22 Dec 6, 2024
274c449
fix(FrappeHR): map companies to workspaces in Raven
nikkothari22 Dec 6, 2024
e42c4c2
fix: translate error message
nikkothari22 Dec 6, 2024
115f90c
fix: remove flicker on dialog closing - downgraded Radix to 3.1.4
nikkothari22 Dec 7, 2024
b546255
fix: HR integration with department channels
nikkothari22 Dec 7, 2024
f0278bd
fix: error page routing
nikkothari22 Dec 7, 2024
ddf72cd
revert: upgrade radix themes because of dep mismatch between vaul and…
nikkothari22 Dec 7, 2024
d75b524
fix: force RadixUI dialog to v1.1.1
nikkothari22 Dec 7, 2024
5ce5f0a
feat: add workspace flow
nikkothari22 Dec 7, 2024
9338190
fix: move settings page
nikkothari22 Dec 7, 2024
75ec1bb
fix: settings page routing
nikkothari22 Dec 7, 2024
63a16f0
fix: route to last workspace and channel automatically on load
nikkothari22 Dec 7, 2024
6047350
fix: do not refetch on error
nikkothari22 Dec 7, 2024
2dbe719
feat: allow Raven Admins to configure settings
nikkothari22 Dec 7, 2024
d749b7a
fix: disable forms if no perms
nikkothari22 Dec 7, 2024
1057b94
feat: empty states for all configuration pages
nikkothari22 Dec 7, 2024
aa200b3
fix: fix settings sidebar
nikkothari22 Dec 7, 2024
916c468
fix: non-workspace-admins cannot create channels
nikkothari22 Dec 7, 2024
eeb1057
fix: limit workspace description to two lines
nikkothari22 Dec 13, 2024
0b55104
fi(ui): setting page UI on mobile
nikkothari22 Dec 13, 2024
cd26552
feat: join and leave workspace flows
nikkothari22 Dec 13, 2024
adad90b
feat: add workspace from list
nikkothari22 Dec 13, 2024
c8ce4fc
feat: workspace member removal and admin management
nikkothari22 Dec 13, 2024
3e22766
fix(ui): loader color
nikkothari22 Dec 14, 2024
45d07d3
feat: workspace member manager
nikkothari22 Dec 14, 2024
0cf9c6b
feat: add members to workspace
nikkothari22 Dec 14, 2024
44fae19
feat: workspace image uploader
nikkothari22 Dec 14, 2024
6a7ffda
fix: only allow search for channels where the user is a member
nikkothari22 Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
perf: use cache for peer user ID
nikkothari22 committed Nov 8, 2024
commit d2bdf60b4c1581be078ca4652afa28ff1dcdb1f4
22 changes: 18 additions & 4 deletions raven/api/raven_channel.py
Original file line number Diff line number Diff line change
@@ -107,21 +107,35 @@ def get_channels(hide_archived=False):
return channels


def get_peer_user_id(channel_id, is_direct_message, is_self_message=False):
def get_peer_user(channel_id: str, is_direct_message: int, is_self_message: bool = False) -> dict:
"""
For a given channel, fetches the user id of the peer
For a given channel, fetches the peer's member object
"""
if is_direct_message == 0:
return None
if is_self_message:
return frappe.session.user
return {
"user_id": frappe.session.user,
}

members = get_channel_members(channel_id)

for member in members:
if member != frappe.session.user:
return member
return members[member]

return None


def get_peer_user_id(
channel_id: str, is_direct_message: int, is_self_message: bool = False
) -> str:
"""
For a given channel, fetches the user id of the peer
"""
peer_user = get_peer_user(channel_id, is_direct_message, is_self_message)
if peer_user:
return peer_user.get("user_id")
return None


8 changes: 3 additions & 5 deletions raven/api/raven_channel_member.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import frappe
from frappe import _

from raven.utils import track_channel_visit
from raven.utils import get_channel_member, track_channel_visit


@frappe.whitelist()
def remove_channel_member(user_id, channel_id):
# Get raven channel member name where user_id and channel_id match
member = frappe.db.get_value(
"Raven Channel Member", {"user_id": user_id, "channel_id": channel_id}, ["name"]
)
member = get_channel_member(channel_id, user_id)
# Delete raven channel member
if member:
frappe.delete_doc("Raven Channel Member", member)
frappe.delete_doc("Raven Channel Member", member["name"])
else:
frappe.throw(_("User is not a member of this channel"))

12 changes: 5 additions & 7 deletions raven/api/raven_message.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
from frappe.query_builder.functions import Coalesce, Count

from raven.api.raven_channel import create_direct_message_channel, get_peer_user_id
from raven.utils import get_channel_member, track_channel_visit
from raven.utils import get_channel_member, is_channel_member, track_channel_visit


@frappe.whitelist(methods=["POST"])
@@ -188,9 +188,7 @@ def parse_messages(messages):

def check_permission(channel_id):
if frappe.get_cached_value("Raven Channel", channel_id, "type") == "Private":
if frappe.db.exists(
"Raven Channel Member", {"channel_id": channel_id, "user_id": frappe.session.user}
):
if is_channel_member(channel_id):
pass
elif frappe.session.user == "Administrator":
pass
@@ -258,7 +256,9 @@ def get_unread_count_for_channels():
def get_unread_count_for_channel(channel_id):
channel_member = get_channel_member(channel_id=channel_id)
if channel_member:
last_timestamp = frappe.get_cached_value("Raven Channel Member", channel_member, "last_visit")
last_timestamp = frappe.get_cached_value(
"Raven Channel Member", channel_member["name"], "last_visit"
)

return frappe.db.count(
"Raven Message",
@@ -280,8 +280,6 @@ def get_unread_count_for_channel(channel_id):
else:
return 0

return 0


@frappe.whitelist()
def get_timeline_message_content(doctype, docname):
9 changes: 4 additions & 5 deletions raven/api/threads.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@
from frappe import _
from frappe.query_builder import Order

from raven.utils import get_channel_members


@frappe.whitelist()
def get_all_threads(is_ai_thread=0):
@@ -54,11 +56,8 @@ def get_all_threads(is_ai_thread=0):

for thread in threads:
# Fetch the participants of the thread
thread["participants"] = frappe.get_all(
"Raven Channel Member",
filters={"channel_id": thread["name"]},
fields=["user_id"],
)
thread_members = get_channel_members(thread["name"])
thread["participants"] = [{"user_id": member} for member in thread_members]

return threads

19 changes: 5 additions & 14 deletions raven/raven_messaging/doctype/raven_message/raven_message.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
from pytz import timezone, utc

from raven.ai.ai import handle_ai_thread_message, handle_bot_dm
from raven.api.raven_channel import get_peer_user
from raven.notification import send_notification_to_topic, send_notification_to_user
from raven.utils import track_channel_visit

@@ -167,13 +168,9 @@ def handle_ai_message(self):
return

# Get the bot user
peer_user = frappe.db.get_value(
"Raven Channel Member",
{"channel_id": self.channel_id, "user_id": ("!=", self.owner)},
"user_id",
)
peer_user = get_peer_user(self.channel_id, is_dm)

if not peer_user:
if not peer_user or peer_user.get("type") != "Bot":
return

# Get the bot user doc
@@ -222,15 +219,9 @@ def publish_unread_count_event(self):

if not channel_doc.is_self_message:

peer_raven_user = frappe.db.get_value(
"Raven Channel Member",
{"channel_id": self.channel_id, "user_id": ("!=", frappe.session.user)},
"user_id",
)

peer_user_doc = frappe.get_cached_doc("Raven User", peer_raven_user)
peer_user_doc = get_peer_user(self.channel_id, 1)

if peer_user_doc.type == "User":
if peer_user_doc.get("type") == "User":

frappe.publish_realtime(
"raven:unread_channel_count_updated",
31 changes: 23 additions & 8 deletions raven/utils.py
Original file line number Diff line number Diff line change
@@ -15,7 +15,9 @@ def track_channel_visit(channel_id, user=None, commit=False, publish_event_for_u

if channel_member:
# Update the last visit
frappe.db.set_value("Raven Channel Member", channel_member, "last_visit", frappe.utils.now())
frappe.db.set_value(
"Raven Channel Member", channel_member["name"], "last_visit", frappe.utils.now()
)

# Else if the user is not a member of the channel and the channel is open, create a new member record
elif frappe.get_cached_value("Raven Channel", channel_id, "type") == "Open":
@@ -69,20 +71,33 @@ def delete_workspace_members_cache(workspace_id: str):

def get_channel_members(channel_id: str):
"""
Gets all members of a channel from the cache as a map
Gets all members of a channel from the cache as a map - also includes the type of the user
"""
cache_key = f"raven:channel_members:{channel_id}"

data = frappe.cache.get_value(cache_key)
if data:
return data

members = frappe.db.get_all(
"Raven Channel Member",
filters={"channel_id": channel_id},
fields=["name", "user_id", "is_admin", "allow_notifications"],
raven_channel_member = frappe.qb.DocType("Raven Channel Member")
raven_user = frappe.qb.DocType("Raven User")

query = (
frappe.qb.from_(raven_channel_member)
.join(raven_user)
.on(raven_channel_member.user_id == raven_user.name)
.select(
raven_channel_member.name,
raven_channel_member.user_id,
raven_channel_member.is_admin,
raven_channel_member.allow_notifications,
raven_user.type,
)
.where(raven_channel_member.channel_id == channel_id)
)

members = query.run(as_dict=True)

data = {member.user_id: member for member in members}
frappe.cache.set_value(cache_key, data)
return data
@@ -93,7 +108,7 @@ def delete_channel_members_cache(channel_id: str):
frappe.cache.delete_value(cache_key)


def get_channel_member(channel_id: str, user: str = None) -> str:
def get_channel_member(channel_id: str, user: str = None) -> dict:
"""
Get the channel member ID
"""
@@ -103,7 +118,7 @@ def get_channel_member(channel_id: str, user: str = None) -> str:

all_members = get_channel_members(channel_id)

return all_members.get(user, {}).get("name")
return all_members.get(user, None)


def is_workspace_member(workspace_id: str, user: str = None) -> bool: