From e3f5939f6cd1ec1ed0477d29118b20a400825dcf Mon Sep 17 00:00:00 2001 From: Antonis Stamatiou Date: Fri, 12 Apr 2024 18:11:01 +0300 Subject: [PATCH 1/5] feat: Perform changes related to CI/CD. Prepare plugin for community migration. (#248) --- .github/workflows/cd.yml | 10 +--------- .github/workflows/ci.yml | 12 +++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index c929fd9b..33307c32 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,18 +1,10 @@ name: cd on: - workflow_run: - workflows: ["ci"] - branches-ignore: ["*"] - types: - - completed push: tags: - "v*" -permissions: - contents: read - jobs: plugin-cd: - uses: mattermost/actions-workflows/.github/workflows/plugin-cd.yml@main + uses: mattermost/actions-workflows/.github/workflows/community-plugin-cd.yml@d9defa3e455bdbf889573e112ad8d05b91d66b4c secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c05ae63..b49d0645 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,12 @@ name: ci on: - schedule: - - cron: "0 0 * * *" + pull_request: push: branches: - master - tags: - - "v*" - pull_request: - -permissions: - contents: read + - main jobs: plugin-ci: - uses: mattermost/actions-workflows/.github/workflows/plugin-ci.yml@main + uses: mattermost/actions-workflows/.github/workflows/community-plugin-ci.yml@139a051e8651e6246e3764fe342297b73120e590 secrets: inherit From d7932b393ab8b9a620da4a5b1973768d3431179e Mon Sep 17 00:00:00 2001 From: Michael Kochell <6913320+mickmister@users.noreply.github.com> Date: Tue, 16 Apr 2024 19:29:40 -0400 Subject: [PATCH 2/5] Fix case where you assign yourself your own todo (#203) * fix case where you assign yourself your own todo * fix indentation * fix playwright test setup --------- Co-authored-by: ayusht2810 --- e2e/playwright/tests/test.list.ts | 3 +-- e2e/playwright/tests/todo_plugin.spec.ts | 6 ++---- server/list.go | 6 ++++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/e2e/playwright/tests/test.list.ts b/e2e/playwright/tests/test.list.ts index 732baaf3..66a82a1a 100644 --- a/e2e/playwright/tests/test.list.ts +++ b/e2e/playwright/tests/test.list.ts @@ -1,9 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {test} from '@playwright/test'; import core from './todo_plugin.spec'; import '../support/init_test'; -test.describe(core.connected); +core.connected(); diff --git a/e2e/playwright/tests/todo_plugin.spec.ts b/e2e/playwright/tests/todo_plugin.spec.ts index 745e6bb6..eb8c08e8 100644 --- a/e2e/playwright/tests/todo_plugin.spec.ts +++ b/e2e/playwright/tests/todo_plugin.spec.ts @@ -13,8 +13,8 @@ import {fillMessage, getTodoBotDMPageURL} from 'support/utils'; export default { connected: () => { test.describe('available commands', () => { - test('with just the main command', async ({pages, page, pw}) => { - + test('with just the main command', async ({page, pw}) => { + const {adminClient, adminUser} = await pw.getAdminClient(); if (adminUser === null) { throw new Error('can not get adminUser'); @@ -22,7 +22,6 @@ export default { const dmURL = await getTodoBotDMPageURL(adminClient, '', adminUser.id); await page.goto(dmURL, {waitUntil: 'load'}); - const c = new pages.ChannelsPage(page); const slash = new SlashCommandSuggestions(page.locator('#suggestionList')); // # Run incomplete command to trigger help @@ -39,4 +38,3 @@ export default { }); }, }; - diff --git a/server/list.go b/server/list.go index 49473f04..e95a2919 100644 --- a/server/list.go +++ b/server/list.go @@ -245,8 +245,10 @@ func (l *listManager) ChangeAssignment(issueID string, userID string, sendTo str return issue.Message, ir.ForeignUserID, nil } - if err := l.store.RemoveReference(userID, issueID, list); err != nil { - return "", "", err + if userID != sendTo { + if err := l.store.RemoveReference(userID, issueID, list); err != nil { + return "", "", err + } } receiverIssue := newIssue(issue.Message, issue.Description, issue.PostID) From b8dff94f7bebfcb7f81f36f588f110e08e34ef9f Mon Sep 17 00:00:00 2001 From: Julien Fabre Date: Tue, 23 Apr 2024 23:00:32 +0200 Subject: [PATCH 3/5] fix(#150): add maxlength on input (#222) * fix(issue#150): add maxlength on input * fix: lint problems --- .../user_selector/autocomplete_selector.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/user_selector/autocomplete_selector.tsx b/webapp/src/components/user_selector/autocomplete_selector.tsx index 09aadf18..9312cabc 100644 --- a/webapp/src/components/user_selector/autocomplete_selector.tsx +++ b/webapp/src/components/user_selector/autocomplete_selector.tsx @@ -3,6 +3,7 @@ import React, {CSSProperties} from 'react'; +import {components} from 'react-select'; import AsyncSelect from 'react-select/async'; import {OptionsType, ValueType, Theme as ComponentTheme} from 'react-select/src/types'; import {Props as ComponentProps, StylesConfig} from 'react-select/src/styles'; @@ -51,7 +52,7 @@ const useTheme = (mattermostTheme: Theme): [StylesConfig, ThemeConfig] => { return [styles, compTheme]; }; -const renderOption = (option: UserProfile, {context} : {context: FormatOptionLabelContext}) => { +const renderOption = (option: UserProfile, {context}: {context: FormatOptionLabelContext}) => { const {username} = option; const name = `@${username}`; const description = getDescription(option); @@ -116,6 +117,13 @@ export default function AutocompleteSelector(props: Props) { ); } + //@ts-ignore + const Input = (inputProps) => ( + ); + return (
Date: Fri, 24 May 2024 13:59:14 +0300 Subject: [PATCH 4/5] Enabling dependabot (#255) Enabling dependabot Ticket: https://mattermost.atlassian.net/browse/CLD-7732 --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..cf559af3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Enable version updates for GOLang dependencies + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "monthly" From 5e3aa74e9e1778df158888cd62f45f457c6b8b42 Mon Sep 17 00:00:00 2001 From: Ayush Thakur <100013900+ayusht2810@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:03:25 +0530 Subject: [PATCH 5/5] [MM-432] Fix issue of todo getting assigned to last assigned user (#253) * [MM-432] Fix issue of todo getting assigned to last assigned user * [MM-432] Add hook and remove prop from component --- .../assignee_modal/assignee_form.jsx | 142 ++++++++++++++++++ .../assignee_modal/assignee_modal.jsx | 135 ++--------------- webapp/src/hooks/useEscapeKey.ts | 17 +++ 3 files changed, 171 insertions(+), 123 deletions(-) create mode 100644 webapp/src/components/assignee_modal/assignee_form.jsx create mode 100644 webapp/src/hooks/useEscapeKey.ts diff --git a/webapp/src/components/assignee_modal/assignee_form.jsx b/webapp/src/components/assignee_modal/assignee_form.jsx new file mode 100644 index 00000000..c52e34ad --- /dev/null +++ b/webapp/src/components/assignee_modal/assignee_form.jsx @@ -0,0 +1,142 @@ +import React, {useState, useCallback} from 'react'; +import PropTypes from 'prop-types'; + +import AutocompleteSelector from '../user_selector/autocomplete_selector'; +import Button from '../../widget/buttons/button'; +import IconButton from '../../widget/iconButton/iconButton'; + +import CompassIcon from '../icons/compassIcons'; + +import {useEscapeKey} from '../../hooks/useEscapeKey'; + +const AssigneeForm = ( + { + close, + autocompleteUsers, + theme, + getAssignee, + removeAssignee, + removeEditingTodo, + changeAssignee, + editingTodo, + }, +) => { + const [assignee, setAssignee] = useState(); + useEscapeKey(close); + const submit = useCallback(() => { + if (editingTodo && assignee) { + changeAssignee(editingTodo, assignee.username); + removeEditingTodo(); + } else if (assignee) { + getAssignee(assignee); + } else { + removeAssignee(); + } + close(); + }, [close, changeAssignee, removeAssignee, getAssignee, assignee, removeEditingTodo, editingTodo]); + + const closeModal = () => { + removeEditingTodo(); + close(); + }; + + const changeAssigneeDropdown = (selected) => { + setAssignee(selected); + }; + + const style = getStyle(theme); + + return ( +
+
+

{'Assign todo to…'}

+ } + /> + +
+ + +
+
+
+ ); +}; + +AssigneeForm.propTypes = { + close: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, + autocompleteUsers: PropTypes.func.isRequired, + getAssignee: PropTypes.func.isRequired, + editingTodo: PropTypes.string.isRequired, + removeAssignee: PropTypes.func.isRequired, + removeEditingTodo: PropTypes.func.isRequired, + changeAssignee: PropTypes.func.isRequired, +}; + +const getStyle = (theme) => ({ + backdrop: { + position: 'absolute', + display: 'flex', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0, 0, 0, 0.50)', + zIndex: 2000, + alignItems: 'center', + justifyContent: 'center', + }, + modal: { + position: 'relative', + width: 600, + padding: 24, + borderRadius: 8, + maxWidth: '100%', + color: theme.centerChannelColor, + backgroundColor: theme.centerChannelBg, + }, + buttons: { + marginTop: 24, + }, + heading: { + fontSize: 20, + fontWeight: 600, + margin: '0 0 24px 0', + }, + closeIcon: { + position: 'absolute', + top: 8, + right: 8, + }, +}); + +export default AssigneeForm; diff --git a/webapp/src/components/assignee_modal/assignee_modal.jsx b/webapp/src/components/assignee_modal/assignee_modal.jsx index 943e08fb..71f8f992 100644 --- a/webapp/src/components/assignee_modal/assignee_modal.jsx +++ b/webapp/src/components/assignee_modal/assignee_modal.jsx @@ -1,11 +1,7 @@ -import React, {useState, useEffect, useCallback} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import AutocompleteSelector from '../user_selector/autocomplete_selector.tsx'; -import Button from '../../widget/buttons/button'; -import IconButton from '../../widget/iconButton/iconButton'; - -import CompassIcon from '../icons/compassIcons'; +import AssigneeForm from './assignee_form'; const AssigneeModal = ( { @@ -20,91 +16,21 @@ const AssigneeModal = ( editingTodo, }, ) => { - const [assignee, setAssignee] = useState(); - - useEffect(() => { - function handleKeypress(e) { - if (e.key === 'Escape' && visible) { - close(); - } - } - - document.addEventListener('keyup', handleKeypress); - - return () => { - document.removeEventListener('keyup', handleKeypress); - }; - }, [visible]); - - const submit = useCallback(() => { - if (editingTodo && assignee) { - changeAssignee(editingTodo, assignee.username); - removeEditingTodo(); - } else if (assignee) { - getAssignee(assignee); - } else { - removeAssignee(); - } - close(); - }, [close, changeAssignee, removeAssignee, getAssignee, assignee, removeEditingTodo, editingTodo]); - if (!visible) { return null; } - const closeModal = () => { - removeEditingTodo(); - close(); - }; - - const changeAssigneeDropdown = (selected) => { - setAssignee(selected); - }; - - const style = getStyle(theme); - return ( -
-
-

{'Assign todo to…'}

- } - /> - -
- - -
-
-
+ ); }; @@ -120,41 +46,4 @@ AssigneeModal.propTypes = { changeAssignee: PropTypes.func.isRequired, }; -const getStyle = (theme) => ({ - backdrop: { - position: 'absolute', - display: 'flex', - top: 0, - left: 0, - right: 0, - bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.50)', - zIndex: 2000, - alignItems: 'center', - justifyContent: 'center', - }, - modal: { - position: 'relative', - width: 600, - padding: 24, - borderRadius: 8, - maxWidth: '100%', - color: theme.centerChannelColor, - backgroundColor: theme.centerChannelBg, - }, - buttons: { - marginTop: 24, - }, - heading: { - fontSize: 20, - fontWeight: 600, - margin: '0 0 24px 0', - }, - closeIcon: { - position: 'absolute', - top: 8, - right: 8, - }, -}); - export default AssigneeModal; diff --git a/webapp/src/hooks/useEscapeKey.ts b/webapp/src/hooks/useEscapeKey.ts new file mode 100644 index 00000000..f6eaf732 --- /dev/null +++ b/webapp/src/hooks/useEscapeKey.ts @@ -0,0 +1,17 @@ +import React, {useEffect} from 'react'; + +export const useEscapeKey = (close: () => void) => { + useEffect(() => { + function handleKeypress(e: any) { + if (e.key === 'Escape') { + close(); + } + } + + document.addEventListener('keyup', handleKeypress); + + return () => { + document.removeEventListener('keyup', handleKeypress); + }; + }, [close]); +};