Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions client/src/components/CreatableSelect/CreatableSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type CreatableSelectProps = {
const CreatableSelect: React.FC<CreatableSelectProps> = ({
error,
label,
className,
name,
...props
}) => (
Expand All @@ -39,6 +40,7 @@ const CreatableSelect: React.FC<CreatableSelectProps> = ({
>
<ReactSelectCreatable
classNamePrefix="react-select"
className={className}
isMulti
{...props}
/>
Expand Down
23 changes: 0 additions & 23 deletions client/src/components/IntegrationItem/Footer.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions client/src/components/IntegrationItem/IntegrationItem.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions client/src/components/IntegrationItem/Tag.tsx

This file was deleted.

19 changes: 0 additions & 19 deletions client/src/components/IntegrationItem/TagList.tsx

This file was deleted.

13 changes: 12 additions & 1 deletion client/src/mutations/integrations.mutations.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
},
});
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
33 changes: 33 additions & 0 deletions client/src/pages/integrations/IntegrationItem/Footer.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="flex">
{category && <Category category={category} />}

{tags && (
<TagList
tags={tags}
remainingTags={remainingTags}
onAddTag={onAddTag}
onDeleteTag={onDeleteTag}
/>
)}

{date && <Date date={date} />}
</div>
);
};

export default Footer;
Original file line number Diff line number Diff line change
@@ -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[] = [
{
Expand Down Expand Up @@ -32,7 +35,7 @@ const Header: React.FC<{
}> = ({id, name, status, description = 'Description not available'}) => {
return (
<div className="relative mb-3 flex items-center justify-between">
<div className="">
<div>
<Status status={status} />

<Name name={name} description={description} />
Expand Down
84 changes: 84 additions & 0 deletions client/src/pages/integrations/IntegrationItem/IntegrationItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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;
onChangeState: () => void;
description?: string;
category?: CategoryModel;
date?: Date;
id?: number;
tags?: Array<TagModel>;
workflowIds?: string[];
remainingTags?: TagModel[];
}> = ({
id,
name,
status,
description,
category,
tags,
date,
remainingTags,
onChangeState,
}) => {
const mutation = useIntegrationTagsMutation();
const [needsRefetch, setNeedsRefetch] = useState(false);

useEffect(() => {
if (needsRefetch) {
setNeedsRefetch(false);
onChangeState();
}
}, [needsRefetch, onChangeState]);

const handleOnAddTag = (newTag: TagModel) => {
const newTags = (tags && [...tags]) || [];
newTags.push(newTag);
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,
putIntegrationTagsRequestModel: {
tags: newTags || [],
},
});

setNeedsRefetch(true);
};

return (
<div>
<Header
id={id}
name={name}
status={status}
description={description}
/>

<Footer
category={category}
tags={tags}
date={date}
remainingTags={remainingTags}
onAddTag={handleOnAddTag}
onDeleteTag={handleOnDeleteTag}
/>
</div>
);
};
19 changes: 19 additions & 0 deletions client/src/pages/integrations/IntegrationItem/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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 (
<span className="inline-flex items-center rounded-full bg-gray-200 px-3 py-1 text-xs text-gray-700">
{tag.name}

<Cross1Icon
className="ml-1.5 h-3 w-3 rounded-full hover:bg-gray-400"
onClick={() => onDeleteTag(tag)}
/>
</span>
);
};
61 changes: 61 additions & 0 deletions client/src/pages/integrations/IntegrationItem/TagList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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[];
onAddTag: (newTag: TagModel) => void;
onDeleteTag: (deletedTag: TagModel) => void;
remainingTags?: TagModel[];
}> = ({tags, remainingTags, onAddTag, onDeleteTag}) => {
const [isNewTagWindowVisible, setIsNewTagWindowVisible] = useState(false);

return (
<div className="mx-4 flex grow space-x-2 pt-2">
{tags.map((tag) => (
<Tag key={tag.id} tag={tag} onDeleteTag={onDeleteTag} />
))}

{!isNewTagWindowVisible ? (
<div
className="self-center"
onClick={() => setIsNewTagWindowVisible(true)}
>
<PlusIcon className="rounded-full hover:bg-gray-400" />
</div>
) : (
<CreatableSelect
name="newTag"
isMulti={false}
options={remainingTags!.map((tag: TagModel) => ({
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]
Comment on lines +49 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtriraš pa uzimaš samo prvi index?

Možda ti je find za to bolji - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

);
setIsNewTagWindowVisible(false);
}}
/>
)}
</div>
);
};
Loading