From 2f6d79201fcf43febe831d3591584b0056b1c9d7 Mon Sep 17 00:00:00 2001 From: Marta Jurcevic Date: Wed, 8 Feb 2023 16:13:02 +0100 Subject: [PATCH 1/4] #167 functionality of add and remove tag in IntegrationItem # Conflicts: # client/package-lock.json --- .../CreatableSelect/CreatableSelect.tsx | 2 + .../src/components/IntegrationItem/Footer.tsx | 23 ------- .../IntegrationItem/IntegrationItem.tsx | 29 --------- .../src/mutations/integrations.mutations.ts | 13 +++- .../IntegrationItem/AddTagButton.tsx | 0 .../IntegrationItem/Category.tsx | 2 +- .../integrations}/IntegrationItem/Date.tsx | 0 .../integrations/IntegrationItem/Footer.tsx | 33 ++++++++++ .../integrations}/IntegrationItem/Header.tsx | 7 ++- .../IntegrationItem/IntegrationItem.tsx | 60 ++++++++++++++++++ .../integrations}/IntegrationItem/Name.tsx | 0 .../integrations}/IntegrationItem/Status.tsx | 0 .../integrations/IntegrationItem/Tag.tsx | 21 +++++++ .../integrations/IntegrationItem/TagList.tsx | 62 +++++++++++++++++++ .../pages/integrations/IntegrationList.tsx | 53 +++++++++------- 15 files changed, 226 insertions(+), 79 deletions(-) delete mode 100644 client/src/components/IntegrationItem/Footer.tsx delete mode 100644 client/src/components/IntegrationItem/IntegrationItem.tsx rename client/src/{components => pages/integrations}/IntegrationItem/AddTagButton.tsx (100%) rename client/src/{components => pages/integrations}/IntegrationItem/Category.tsx (87%) rename client/src/{components => pages/integrations}/IntegrationItem/Date.tsx (100%) create mode 100644 client/src/pages/integrations/IntegrationItem/Footer.tsx rename client/src/{components => pages/integrations}/IntegrationItem/Header.tsx (88%) create mode 100644 client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx rename client/src/{components => pages/integrations}/IntegrationItem/Name.tsx (100%) rename client/src/{components => pages/integrations}/IntegrationItem/Status.tsx (100%) create mode 100644 client/src/pages/integrations/IntegrationItem/Tag.tsx create mode 100644 client/src/pages/integrations/IntegrationItem/TagList.tsx diff --git a/client/src/components/CreatableSelect/CreatableSelect.tsx b/client/src/components/CreatableSelect/CreatableSelect.tsx index 5eb1ad5ef8e..508b3790b5d 100644 --- a/client/src/components/CreatableSelect/CreatableSelect.tsx +++ b/client/src/components/CreatableSelect/CreatableSelect.tsx @@ -18,6 +18,7 @@ type CreatableSelectProps = { const CreatableSelect: React.FC = ({ error, label, + className, name, ...props }) => ( @@ -39,6 +40,7 @@ const CreatableSelect: React.FC = ({ > diff --git a/client/src/components/IntegrationItem/Footer.tsx b/client/src/components/IntegrationItem/Footer.tsx deleted file mode 100644 index 14a6a8dbba9..00000000000 --- a/client/src/components/IntegrationItem/Footer.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import {Category} from './Category'; -import {Date} from './Date'; -import {TagList} from './TagList'; -import {CategoryModel, TagModel} from '../../data-access/integration'; - -const Footer: React.FC<{ - category?: CategoryModel; - tags?: TagModel[]; - date?: Date; -}> = ({category, tags, date}) => { - return ( -
- {category && } - - {tags && } - - {date && } -
- ); -}; - -export default Footer; diff --git a/client/src/components/IntegrationItem/IntegrationItem.tsx b/client/src/components/IntegrationItem/IntegrationItem.tsx deleted file mode 100644 index 7a22364f13c..00000000000 --- a/client/src/components/IntegrationItem/IntegrationItem.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import Footer from './Footer'; -import Header from './Header'; -import {CategoryModel, TagModel} from '../../data-access/integration'; - -export const IntegrationItem: React.FC<{ - button: string; - name: string; - status: boolean; - description?: string; - category?: CategoryModel; - date?: Date; - id?: number; - tags?: TagModel[]; - workflowIds?: string[]; -}> = ({id, name, status, description, category, tags, date}) => { - return ( -
-
- -
-
- ); -}; diff --git a/client/src/mutations/integrations.mutations.ts b/client/src/mutations/integrations.mutations.ts index 3974ce67e80..e986766e636 100644 --- a/client/src/mutations/integrations.mutations.ts +++ b/client/src/mutations/integrations.mutations.ts @@ -1,5 +1,9 @@ import {useMutation} from '@tanstack/react-query'; -import {IntegrationModel, IntegrationsApi} from 'data-access/integration'; +import { + IntegrationModel, + IntegrationsApi, + PutIntegrationTagsRequest, +} from 'data-access/integration'; type MutationProps = { onSuccess?: (result: IntegrationModel, variables: IntegrationModel) => void; @@ -16,3 +20,10 @@ export const useIntegrationMutation = (mutationProps?: MutationProps) => onSuccess: mutationProps?.onSuccess, onError: mutationProps?.onError, }); + +export const useIntegrationTagsMutation = () => + useMutation({ + mutationFn: (request: PutIntegrationTagsRequest) => { + return new IntegrationsApi().putIntegrationTags(request); + }, + }); diff --git a/client/src/components/IntegrationItem/AddTagButton.tsx b/client/src/pages/integrations/IntegrationItem/AddTagButton.tsx similarity index 100% rename from client/src/components/IntegrationItem/AddTagButton.tsx rename to client/src/pages/integrations/IntegrationItem/AddTagButton.tsx diff --git a/client/src/components/IntegrationItem/Category.tsx b/client/src/pages/integrations/IntegrationItem/Category.tsx similarity index 87% rename from client/src/components/IntegrationItem/Category.tsx rename to client/src/pages/integrations/IntegrationItem/Category.tsx index b6d7095f3bb..9f588366206 100644 --- a/client/src/components/IntegrationItem/Category.tsx +++ b/client/src/pages/integrations/IntegrationItem/Category.tsx @@ -1,6 +1,6 @@ import {Squares2X2Icon} from '@heroicons/react/24/outline'; import React from 'react'; -import {CategoryModel} from '../../data-access/integration'; +import {CategoryModel} from '../../../data-access/integration'; export const Category: React.FC<{category: CategoryModel}> = ({category}) => { return ( diff --git a/client/src/components/IntegrationItem/Date.tsx b/client/src/pages/integrations/IntegrationItem/Date.tsx similarity index 100% rename from client/src/components/IntegrationItem/Date.tsx rename to client/src/pages/integrations/IntegrationItem/Date.tsx diff --git a/client/src/pages/integrations/IntegrationItem/Footer.tsx b/client/src/pages/integrations/IntegrationItem/Footer.tsx new file mode 100644 index 00000000000..0b18d88aea6 --- /dev/null +++ b/client/src/pages/integrations/IntegrationItem/Footer.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import {Category} from './Category'; +import {Date} from './Date'; +import {TagList} from './TagList'; +import {CategoryModel, TagModel} from '../../../data-access/integration'; + +const Footer: React.FC<{ + category?: CategoryModel; + tags?: TagModel[]; + date?: Date; + remainingTags?: TagModel[]; + onAddTag: (newTag: TagModel) => void; + onDeleteTag: (deletedTag: TagModel) => void; +}> = ({category, tags, date, remainingTags, onAddTag, onDeleteTag}) => { + return ( +
+ {category && } + + {tags && ( + + )} + + {date && } +
+ ); +}; + +export default Footer; diff --git a/client/src/components/IntegrationItem/Header.tsx b/client/src/pages/integrations/IntegrationItem/Header.tsx similarity index 88% rename from client/src/components/IntegrationItem/Header.tsx rename to client/src/pages/integrations/IntegrationItem/Header.tsx index e6747d58600..74061b5f223 100644 --- a/client/src/components/IntegrationItem/Header.tsx +++ b/client/src/pages/integrations/IntegrationItem/Header.tsx @@ -1,7 +1,10 @@ import React from 'react'; import {Name} from './Name'; import {Status} from './Status'; -import {Dropdown, DropDownMenuItem} from '../DropDown/Dropdown'; +import { + Dropdown, + DropDownMenuItem, +} from '../../../components/DropDown/Dropdown'; const menuItems: DropDownMenuItem[] = [ { @@ -32,7 +35,7 @@ const Header: React.FC<{ }> = ({id, name, status, description = 'Description not available'}) => { return (
-
+
diff --git a/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx b/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx new file mode 100644 index 00000000000..baa8dfbdb91 --- /dev/null +++ b/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx @@ -0,0 +1,60 @@ +import React, {useEffect, useState} from 'react'; +import Footer from './Footer'; +import Header from './Header'; +import {CategoryModel, TagModel} from '../../../data-access/integration'; +import {useIntegrationTagsMutation} from 'mutations/integrations.mutations'; + +export const IntegrationItem: React.FC<{ + button: string; + name: string; + status: boolean; + description?: string; + category?: CategoryModel; + date?: Date; + id?: number; + tags?: TagModel[]; + workflowIds?: string[]; + remainingTags?: TagModel[]; +}> = ({id, name, status, description, category, tags, date, remainingTags}) => { + const mutation = useIntegrationTagsMutation(); + const [reload, setReload] = useState(false); + + useEffect(() => { + if (reload) { + window.location.reload(); + } + }, [reload]); + + const handleOnAddTag = (newTag: TagModel) => { + const newTags = (tags && [...tags]) || []; + newTags.push(newTag); + mutation.mutate({id: id || 0, tagModel: newTags || []}); + setReload(true); + }; + + const handleOnDeleteTag = (deletedTag: TagModel) => { + const newTags = tags?.filter((tag) => tag.id !== deletedTag.id) || []; + mutation.mutate({id: id || 0, tagModel: newTags}); + setReload(true); + }; + + return ( +
+
+ +
+
+ ); +}; diff --git a/client/src/components/IntegrationItem/Name.tsx b/client/src/pages/integrations/IntegrationItem/Name.tsx similarity index 100% rename from client/src/components/IntegrationItem/Name.tsx rename to client/src/pages/integrations/IntegrationItem/Name.tsx diff --git a/client/src/components/IntegrationItem/Status.tsx b/client/src/pages/integrations/IntegrationItem/Status.tsx similarity index 100% rename from client/src/components/IntegrationItem/Status.tsx rename to client/src/pages/integrations/IntegrationItem/Status.tsx diff --git a/client/src/pages/integrations/IntegrationItem/Tag.tsx b/client/src/pages/integrations/IntegrationItem/Tag.tsx new file mode 100644 index 00000000000..158d18f0f34 --- /dev/null +++ b/client/src/pages/integrations/IntegrationItem/Tag.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import {Cross1Icon} from '@radix-ui/react-icons'; +import {TagModel} from '../../../data-access/integration'; + +export const Tag: React.FC<{ + tag: TagModel; + onDeleteTag: (deletedTag: TagModel) => void; +}> = ({tag, onDeleteTag}) => { + return ( + <> + + {tag.name} + + onDeleteTag(tag)} + /> + + + ); +}; diff --git a/client/src/pages/integrations/IntegrationItem/TagList.tsx b/client/src/pages/integrations/IntegrationItem/TagList.tsx new file mode 100644 index 00000000000..28546a4996d --- /dev/null +++ b/client/src/pages/integrations/IntegrationItem/TagList.tsx @@ -0,0 +1,62 @@ +import React, {useState} from 'react'; + +import {Tag} from './Tag'; +import {PlusIcon} from '@radix-ui/react-icons'; +import {TagModel} from '../../../data-access/integration'; +import CreatableSelect from 'react-select/creatable'; + +export const TagList: React.FC<{ + tags: TagModel[]; + remainingTags?: TagModel[]; + onAddTag: (newTag: TagModel) => void; + onDeleteTag: (deletedTag: TagModel) => void; +}> = ({tags, remainingTags, onAddTag, onDeleteTag}) => { + const [isNewTagWindowVisible, setIsNewTagWindowVisible] = useState(false); + + return ( +
+ {tags.map((tag) => ( + + ))} + + {!isNewTagWindowVisible ? ( +
setIsNewTagWindowVisible(true)} + > + +
+ ) : ( + ({ + label: `${tag.name + .charAt(0) + .toUpperCase()}${tag.name.slice(1)}`, + value: tag.name.toLowerCase().replace(/\W/g, ''), + ...tag, + }))} + onCreateOption={(inputValue: string) => { + onAddTag({ + name: inputValue, + }); + setIsNewTagWindowVisible(false); + }} + onChange={(selectedOption) => { + remainingTags && + onAddTag( + remainingTags.filter( + (tag) => + tag.id != null && + tag.id === selectedOption!.id + )[0] + ); + setIsNewTagWindowVisible(false); + }} + /> + )} +
+ ); +}; diff --git a/client/src/pages/integrations/IntegrationList.tsx b/client/src/pages/integrations/IntegrationList.tsx index e80aa5f3410..9bfcc02771a 100644 --- a/client/src/pages/integrations/IntegrationList.tsx +++ b/client/src/pages/integrations/IntegrationList.tsx @@ -1,6 +1,9 @@ -import {useGetIntegrationsQuery} from '../../queries/integrations.queries'; +import { + useGetIntegrationsQuery, + useGetIntegrationTagsQuery, +} from '../../queries/integrations.queries'; import React from 'react'; -import {IntegrationItem} from 'components/IntegrationItem/IntegrationItem'; +import {IntegrationItem} from 'pages/integrations/IntegrationItem/IntegrationItem'; import {Link, useSearchParams} from 'react-router-dom'; const IntegrationList: React.FC = () => { @@ -19,6 +22,8 @@ const IntegrationList: React.FC = () => { : undefined, }); + const {data: tags} = useGetIntegrationTagsQuery(); + return (
    @@ -35,28 +40,30 @@ const IntegrationList: React.FC = () => { ) : ( integrations.map((integration) => (
    - -
  • - -
  • - + > */} +
  • + + integration.tags?.findIndex( + (x) => x.id === tag.id + ) === -1 + )} + /> +
  • + {/* */}
    )) ))} From e21dadc3d39ab0836f6dfeef505eb4675c755cff Mon Sep 17 00:00:00 2001 From: Marta Jurcevic Date: Mon, 13 Feb 2023 15:30:36 +0100 Subject: [PATCH 2/4] Issue #167 using guery refetch --- .../IntegrationItem/IntegrationItem.tsx | 44 ++++++++++++++----- .../integrations/IntegrationItem/Tag.tsx | 16 +++---- .../integrations/IntegrationItem/TagList.tsx | 5 +-- .../pages/integrations/IntegrationList.tsx | 4 ++ client/src/queries/integrations.queries.ts | 1 + 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx b/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx index baa8dfbdb91..b5c32fcbb87 100644 --- a/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx +++ b/client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx @@ -8,34 +8,58 @@ export const IntegrationItem: React.FC<{ button: string; name: string; status: boolean; + onChangeState: () => void; description?: string; category?: CategoryModel; date?: Date; id?: number; - tags?: TagModel[]; + tags?: Array; workflowIds?: string[]; remainingTags?: TagModel[]; -}> = ({id, name, status, description, category, tags, date, remainingTags}) => { +}> = ({ + id, + name, + status, + description, + category, + tags, + date, + remainingTags, + onChangeState, +}) => { const mutation = useIntegrationTagsMutation(); - const [reload, setReload] = useState(false); + const [needsRefetch, setNeedsRefetch] = useState(false); useEffect(() => { - if (reload) { - window.location.reload(); + if (needsRefetch) { + setNeedsRefetch(false); + onChangeState(); } - }, [reload]); + }, [needsRefetch, onChangeState]); const handleOnAddTag = (newTag: TagModel) => { const newTags = (tags && [...tags]) || []; newTags.push(newTag); - mutation.mutate({id: id || 0, tagModel: newTags || []}); - setReload(true); + mutation.mutate({ + id: id || 0, + putIntegrationTagsRequestModel: { + tags: newTags || [], + }, + }); + + setNeedsRefetch(true); }; const handleOnDeleteTag = (deletedTag: TagModel) => { const newTags = tags?.filter((tag) => tag.id !== deletedTag.id) || []; - mutation.mutate({id: id || 0, tagModel: newTags}); - setReload(true); + mutation.mutate({ + id: id || 0, + putIntegrationTagsRequestModel: { + tags: newTags || [], + }, + }); + + setNeedsRefetch(true); }; return ( diff --git a/client/src/pages/integrations/IntegrationItem/Tag.tsx b/client/src/pages/integrations/IntegrationItem/Tag.tsx index 158d18f0f34..69f7e0d74d5 100644 --- a/client/src/pages/integrations/IntegrationItem/Tag.tsx +++ b/client/src/pages/integrations/IntegrationItem/Tag.tsx @@ -7,15 +7,13 @@ export const Tag: React.FC<{ onDeleteTag: (deletedTag: TagModel) => void; }> = ({tag, onDeleteTag}) => { return ( - <> - - {tag.name} + + {tag.name} - onDeleteTag(tag)} - /> - - + onDeleteTag(tag)} + /> + ); }; diff --git a/client/src/pages/integrations/IntegrationItem/TagList.tsx b/client/src/pages/integrations/IntegrationItem/TagList.tsx index 28546a4996d..5d30ccde4b3 100644 --- a/client/src/pages/integrations/IntegrationItem/TagList.tsx +++ b/client/src/pages/integrations/IntegrationItem/TagList.tsx @@ -7,9 +7,9 @@ import CreatableSelect from 'react-select/creatable'; export const TagList: React.FC<{ tags: TagModel[]; - remainingTags?: TagModel[]; onAddTag: (newTag: TagModel) => void; onDeleteTag: (deletedTag: TagModel) => void; + remainingTags?: TagModel[]; }> = ({tags, remainingTags, onAddTag, onDeleteTag}) => { const [isNewTagWindowVisible, setIsNewTagWindowVisible] = useState(false); @@ -28,8 +28,7 @@ export const TagList: React.FC<{
) : ( ({ label: `${tag.name diff --git a/client/src/pages/integrations/IntegrationList.tsx b/client/src/pages/integrations/IntegrationList.tsx index 9bfcc02771a..ef0c13d51ef 100644 --- a/client/src/pages/integrations/IntegrationList.tsx +++ b/client/src/pages/integrations/IntegrationList.tsx @@ -13,6 +13,7 @@ const IntegrationList: React.FC = () => { isLoading, error, data: integrations, + refetch, } = useGetIntegrationsQuery({ categoryId: searchParams.get('categoryId') ? +searchParams.get('categoryId')! @@ -61,6 +62,9 @@ const IntegrationList: React.FC = () => { (x) => x.id === tag.id ) === -1 )} + onChangeState={() => { + refetch; + }} /> {/* */} diff --git a/client/src/queries/integrations.queries.ts b/client/src/queries/integrations.queries.ts index bcaf65e77fd..31d4713472b 100644 --- a/client/src/queries/integrations.queries.ts +++ b/client/src/queries/integrations.queries.ts @@ -39,5 +39,6 @@ export const useGetIntegrationsQuery = ( () => new IntegrationsApi().getIntegrations(requestParameters), { staleTime: 1 * 60 * 1000, + refetchInterval: 1000, } ); From 0eeb2dd364b1b93d0a426d414dcfceecff09c727 Mon Sep 17 00:00:00 2001 From: Marta Jurcevic Date: Tue, 14 Feb 2023 11:07:08 +0100 Subject: [PATCH 3/4] adding link --- .../pages/integrations/IntegrationList.tsx | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/client/src/pages/integrations/IntegrationList.tsx b/client/src/pages/integrations/IntegrationList.tsx index ef0c13d51ef..1f277a8fe57 100644 --- a/client/src/pages/integrations/IntegrationList.tsx +++ b/client/src/pages/integrations/IntegrationList.tsx @@ -41,33 +41,37 @@ const IntegrationList: React.FC = () => { ) : ( integrations.map((integration) => (
- {/* */} -
  • - - integration.tags?.findIndex( - (x) => x.id === tag.id - ) === -1 - )} - onChangeState={() => { - refetch; - }} - /> -
  • - {/* */} + > +
  • + + integration.tags?.findIndex( + (x) => x.id === tag.id + ) === -1 + )} + onChangeState={() => { + refetch; + }} + /> +
  • +
    )) ))} From 7541497ce7a767bfb3fc389fe7a2d33502f8e3e3 Mon Sep 17 00:00:00 2001 From: Marta Jurcevic Date: Tue, 14 Feb 2023 11:34:09 +0100 Subject: [PATCH 4/4] deleting IntegrationItem --- client/src/components/IntegrationItem/Tag.tsx | 13 ------------- .../components/IntegrationItem/TagList.tsx | 19 ------------------- 2 files changed, 32 deletions(-) delete mode 100644 client/src/components/IntegrationItem/Tag.tsx delete mode 100644 client/src/components/IntegrationItem/TagList.tsx diff --git a/client/src/components/IntegrationItem/Tag.tsx b/client/src/components/IntegrationItem/Tag.tsx deleted file mode 100644 index e4b28d719bd..00000000000 --- a/client/src/components/IntegrationItem/Tag.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import {Cross1Icon} from '@radix-ui/react-icons'; -import {TagModel} from '../../data-access/integration'; - -export const Tag: React.FC<{tag: TagModel}> = ({tag}) => { - return ( - - {tag.name} - - - - ); -}; diff --git a/client/src/components/IntegrationItem/TagList.tsx b/client/src/components/IntegrationItem/TagList.tsx deleted file mode 100644 index 7bc45958e06..00000000000 --- a/client/src/components/IntegrationItem/TagList.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; - -import {Tag} from './Tag'; -import {PlusIcon} from '@radix-ui/react-icons'; -import {TagModel} from '../../data-access/integration'; - -export const TagList: React.FC<{tags: TagModel[]}> = ({tags}) => { - return ( -
    - {tags.map((tag) => ( - - ))} - -
    - -
    -
    - ); -};