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(Mattermost Plugin): Cleanup sidepanel #10798

Merged
merged 13 commits into from
Feb 7, 2025
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import graphql from 'babel-plugin-relay/macro'
import {useEffect, useState} from 'react'
import {Client4} from 'mattermost-redux/client'
import {useEffect, useMemo, useState} from 'react'
import {useDispatch} from 'react-redux'
import {useLazyLoadQuery, useMutation} from 'react-relay'

import {closeCreateTaskModal} from '../../reducers'
import {closeCreateTaskModal, openLinkTeamModal} from '../../reducers'

import {useCurrentChannel} from '../../hooks/useCurrentChannel'
import {useCurrentUser} from '../../hooks/useCurrentUser'
import Select from '../Select'
import SimpleSelect from '../SimpleSelect'

import {Post} from 'mattermost-redux/types/posts'
import {TipTapEditor} from 'parabol-client/components/promptResponse/TipTapEditor'
import useEventCallback from 'parabol-client/hooks/useEventCallback'
import {convertTipTapTaskContent} from 'parabol-client/shared/tiptap/convertTipTapTaskContent'
Expand All @@ -21,9 +25,13 @@ import Modal from '../Modal'
const TaskStatus: TaskStatusEnum[] = ['active', 'done', 'future', 'stuck']

const CreateTaskModal = () => {
const channel = useCurrentChannel()
const mmUser = useCurrentUser()

const data = useLazyLoadQuery<CreateTaskModalQuery>(
graphql`
query CreateTaskModalQuery {
query CreateTaskModalQuery($channel: ID!) {
linkedTeamIds(channel: $channel)
viewer {
id
teams {
Expand All @@ -38,11 +46,17 @@ const CreateTaskModal = () => {
}
}
`,
{}
{
channel: channel?.id ?? ''
}
)

const {viewer} = data
const {viewer, linkedTeamIds} = data
const {id: userId, teams} = viewer
const linkedTeams = useMemo(
() => teams.filter(({id}) => linkedTeamIds && linkedTeamIds.includes(id)),
[teams, linkedTeamIds]
)

const [createTask, createTaskLoading] = useMutation<CreateTaskModalMutation>(graphql`
mutation CreateTaskModalMutation($newTask: CreateTaskInput!) {
Expand All @@ -66,6 +80,7 @@ const CreateTaskModal = () => {
}
}, [teams, selectedTeam])
const teamId = selectedTeam?.id
const teamName = selectedTeam?.name

const dispatch = useDispatch()
const handleClose = () => {
Expand Down Expand Up @@ -93,6 +108,20 @@ const CreateTaskModal = () => {
}
})

if (channel) {
const message = `Task created in [${teamName}](www.example.com)`
Client4.doFetch(`${Client4.getPostsRoute()}/ephemeral`, {
method: 'post',
body: JSON.stringify({
user_id: mmUser.id,
post: {
channel_id: channel.id,
message
}
} as Partial<Post>)
})
}

handleClose()
})

Expand All @@ -101,6 +130,23 @@ const CreateTaskModal = () => {
return null
}

if (linkedTeams.length === 0) {
const handleLink = () => {
dispatch(openLinkTeamModal())
handleClose()
}
return (
<Modal
title='Add a Task'
commitButtonLabel='Link team'
handleClose={handleClose}
handleCommit={handleLink}
>
<p>There are no Parabol teams linked to this channel yet.</p>
</Modal>
)
}

return (
<Modal
title='Add a Task'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import graphql from 'babel-plugin-relay/macro'
import {useEffect, useMemo, useState} from 'react'
import {useDispatch, useSelector} from 'react-redux'
import {useDispatch} from 'react-redux'
import {useLazyLoadQuery} from 'react-relay'

import {closeInviteToMeetingModal} from '../../reducers'

import Select from '../Select'

import {Client4} from 'mattermost-redux/client'
import {getCurrentUser} from 'mattermost-redux/selectors/entities/common'
import {Post} from 'mattermost-redux/types/posts'
import {PALETTE} from '~/styles/paletteV3'
import {InviteToMeetingModalQuery} from '../../__generated__/InviteToMeetingModalQuery.graphql'
import {useCurrentChannel} from '../../hooks/useCurrentChannel'
import useMassInvitationToken from '../../hooks/useMassInvitationToken'
import {useInviteToMeeting} from '../../hooks/useInviteToMeeting'
import LoadingSpinner from '../LoadingSpinner'
import Modal from '../Modal'

Expand All @@ -22,31 +18,25 @@ const InviteToMeetingModal = () => {
const data = useLazyLoadQuery<InviteToMeetingModalQuery>(
graphql`
query InviteToMeetingModalQuery($channel: ID!) {
config {
parabolUrl
}
linkedTeamIds(channel: $channel)
viewer {
teams {
id
name
activeMeetings {
...useInviteToMeeting_meeting
id
teamId
name
meetingType
}
}
}
}
`,
{
channel: channel.id
channel: channel?.id ?? ''
}
)

const {viewer, config, linkedTeamIds} = data
const parabolUrl = config?.parabolUrl
const {viewer, linkedTeamIds} = data
const {teams} = viewer
const linkedTeams = useMemo(
() => viewer.teams.filter((team) => !linkedTeamIds || linkedTeamIds.includes(team.id)),
Expand All @@ -65,65 +55,18 @@ const InviteToMeetingModal = () => {
}
}, [activeMeetings, selectedMeeting])

const getToken = useMassInvitationToken({
teamId: selectedMeeting?.teamId,
meetingId: selectedMeeting?.id
})

const currentUser = useSelector(getCurrentUser)
const invite = useInviteToMeeting(selectedMeeting)

const dispatch = useDispatch()
const handleClose = () => {
dispatch(closeInviteToMeetingModal())
}

const handleStart = async () => {
if (!selectedMeeting) {
return
}
const {name: meetingName, id: meetingId} = selectedMeeting
const token = await getToken()
if (!token) {
if (!selectedMeeting || !channel) {
return
}
const team = linkedTeams.find((team) => team.id === selectedMeeting.teamId)!
const teamName = team.name
const inviteUrl = `${parabolUrl}/invitation-link/${token}`
const meetingUrl = `${parabolUrl}/meet/${meetingId}`
const {username, nickname, first_name, last_name} = currentUser
const userName = nickname || username || `${first_name} ${last_name}`
const props = {
attachments: [
{
fallback: `${userName} invited you to join the meeting ${meetingName}`,
title: `${userName} invited you to join a meeting in [Parabol](${meetingUrl})`,
color: PALETTE.GRAPE_500,
fields: [
{
short: true,
title: 'Team',
value: teamName
},
{
short: true,
title: 'Meeting',
value: meetingName
},
{
short: false,
value: `
| [Join Meeting](${inviteUrl}) |
|:--------------------:|
||`
}
]
}
]
}
Client4.createPost({
channel_id: channel.id,
props
} as Partial<Post> as Post)
invite?.()
handleClose()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import graphql from 'babel-plugin-relay/macro'
import {useEffect, useState} from 'react'
import {useDispatch, useSelector} from 'react-redux'
import {useDispatch} from 'react-redux'
import {useLazyLoadQuery} from 'react-relay'

import {closeInviteToTeamModal} from '../../reducers'

import Select from '../Select'

import {Client4} from 'mattermost-redux/client'
import {getCurrentUser} from 'mattermost-redux/selectors/entities/common'
import {Post} from 'mattermost-redux/types/posts'
import {PALETTE} from '~/styles/paletteV3'
import {InviteToTeamModalQuery} from '../../__generated__/InviteToTeamModalQuery.graphql'
import {useCurrentChannel} from '../../hooks/useCurrentChannel'
import useMassInvitationToken from '../../hooks/useMassInvitationToken'
import {useInviteToTeam} from '../../hooks/useInviteToTeam'
import LoadingSpinner from '../LoadingSpinner'
import Modal from '../Modal'

const InviteToTeamModal = () => {
const data = useLazyLoadQuery<InviteToTeamModalQuery>(
graphql`
query InviteToTeamModalQuery {
config {
parabolUrl
}
viewer {
teams {
...useInviteToTeam_team
id
name
}
Expand All @@ -35,8 +29,7 @@ const InviteToTeamModal = () => {
{}
)

const {viewer, config} = data
const parabolUrl = config?.parabolUrl
const {viewer} = data
const {teams} = viewer

const [selectedTeam, setSelectedTeam] = useState<NonNullable<typeof teams>[number]>()
Expand All @@ -48,51 +41,18 @@ const InviteToTeamModal = () => {
}
}, [teams, selectedTeam])

const getToken = useMassInvitationToken({teamId: selectedTeam?.id})

const currentUser = useSelector(getCurrentUser)
const invite = useInviteToTeam(selectedTeam)

const dispatch = useDispatch()
const handleClose = () => {
dispatch(closeInviteToTeamModal())
}

const handleStart = async () => {
if (!selectedTeam) {
return
}
const {id: teamId, name: teamName} = selectedTeam
const token = await getToken()
if (!token) {
if (!selectedTeam || !channel) {
return
}
const inviteUrl = `${parabolUrl}/invitation-link/${token}`
const teamUrl = `${parabolUrl}/team/${teamId}`
const {username, nickname, first_name, last_name} = currentUser
const userName = nickname || username || `${first_name} ${last_name}`
const props = {
attachments: [
{
title: `${userName} invited you to join a team in [Parabol](${teamUrl})`,
fallback: `${userName} invited you to join a team ${teamName} in Parabol`,
color: PALETTE.GRAPE_500,
fields: [
{short: true, value: teamName},
{
short: false,
value: `
| [Join Team](${inviteUrl}) |
|:--------------------:|
||`
}
]
}
]
}
Client4.createPost({
channel_id: channel.id,
props
} as Partial<Post> as Post)
invite()
handleClose()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const LinkTeamModal = () => {
}
`,
{
channel: channel.id
channel: channel?.id ?? ''
}
)
const {viewer, linkedTeamIds} = data
Expand Down Expand Up @@ -58,7 +58,7 @@ const LinkTeamModal = () => {
handleClose()
}

if (!isVisible) {
if (!isVisible || !channel) {
return null
}

Expand Down
8 changes: 1 addition & 7 deletions packages/mattermost-plugin/components/LoadingSpinner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//import classNames from 'classnames'
import React from 'react'

type Props = {
Expand All @@ -7,12 +6,7 @@ type Props = {
}
const LoadingSpinner = ({text, style}: Props) => {
return (
<span
id='loadingSpinner'
//className={classNames('LoadingSpinner', {'with-text': Boolean(text)})}
style={style}
data-testid='loadingSpinner'
>
<span id='loadingSpinner' style={style} data-testid='loadingSpinner'>
<span className='fa fa-spinner fa-fw fa-pulse spinner' />
{text}
</span>
Expand Down
4 changes: 2 additions & 2 deletions packages/mattermost-plugin/components/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DotsVerticalIcon} from '@mattermost/compass-icons/components'
import {MoreVert} from '@mui/icons-material'
import {IconButton, Menu, MenuItem} from '@mui/material'
import React from 'react'

Expand Down Expand Up @@ -30,7 +30,7 @@ const MoreMenu = ({options}: Props) => {
aria-haspopup='true'
onClick={handleOpen}
>
<DotsVerticalIcon />
<MoreVert />
</IconButton>
<Menu
id='long-menu'
Expand Down
2 changes: 1 addition & 1 deletion packages/mattermost-plugin/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const Modal = (props: ModalProps) => {
>
<M.Header closeButton={true}>
<M.Title>
<img width={36} height={36} src={`${assetsPath}/parabol.png`} />
<img width={36} height={36} className='mr-3' src={`${assetsPath}/parabol.png`} />
{title}
</M.Title>
</M.Header>
Expand Down
Loading