@@ -12,7 +12,12 @@ import { useT } from '@gitroom/react/translation/get.transation.service.client';
1212import { useClickOutside } from '@mantine/hooks' ;
1313import clsx from 'clsx' ;
1414import { useModals } from '@gitroom/frontend/components/layout/new-modal' ;
15- import { TagIcon , DropdownArrowIcon , PlusIcon , CheckmarkIcon } from '@gitroom/frontend/components/ui/icons' ;
15+ import {
16+ TagIcon ,
17+ DropdownArrowIcon ,
18+ PlusIcon ,
19+ CheckmarkIcon ,
20+ } from '@gitroom/frontend/components/ui/icons' ;
1621
1722export const TagsComponent : FC < {
1823 name : string ;
@@ -54,7 +59,9 @@ export const TagsComponentInner: FC<{
5459 } ) => void ;
5560} > = ( { initial, onChange, name, mutate, allTags : data } ) => {
5661 const t = useT ( ) ;
62+ const fetch = useFetch ( ) ;
5763 const [ isOpen , setIsOpen ] = useState ( false ) ;
64+ const [ allowClose , setAllowClose ] = useState ( true ) ;
5865 const [ tagValue , setTagValue ] = useState < any [ ] > (
5966 ( initial ?. slice ( 0 ) || [ ] ) . map ( ( p : any ) => {
6067 return data ?. tags . find ( ( a : any ) => a . name === p . value ) || p ;
@@ -63,7 +70,7 @@ export const TagsComponentInner: FC<{
6370 const modals = useModals ( ) ;
6471
6572 const ref = useClickOutside ( ( ) => {
66- if ( ! isOpen ) {
73+ if ( ! isOpen || ! allowClose ) {
6774 return ;
6875 }
6976 setIsOpen ( false ) ;
@@ -98,6 +105,58 @@ export const TagsComponentInner: FC<{
98105 }
99106 } , [ ] ) ;
100107
108+ const deleteTag = useCallback (
109+ async ( tag : any , e : React . MouseEvent ) => {
110+ setAllowClose ( false ) ;
111+ e . stopPropagation ( ) ;
112+ const confirmed : boolean = await new Promise ( ( resolve ) => {
113+ modals . openModal ( {
114+ title : t ( 'delete_tag' , 'Delete Tag' ) ,
115+ children : ( close ) => (
116+ < ConfirmDeleteModal
117+ tagName = { tag . name }
118+ close = { close }
119+ resolve = { resolve }
120+ />
121+ ) ,
122+ } ) ;
123+ } ) ;
124+
125+ if ( ! confirmed ) {
126+ setTimeout ( ( ) => {
127+ setAllowClose ( true ) ;
128+ } , 500 ) ;
129+ return ;
130+ }
131+
132+ await fetch ( `/posts/tags/${ tag . id } ` , {
133+ method : 'DELETE' ,
134+ } ) ;
135+
136+ // Remove the tag from current selection if it was selected
137+ const modify = tagValue . filter ( ( a ) => a . id !== tag . id ) ;
138+ if ( modify . length !== tagValue . length ) {
139+ setTagValue ( modify ) ;
140+ onChange ( {
141+ target : {
142+ value : modify . map ( ( p : any ) => ( {
143+ label : p . name ,
144+ value : p . name ,
145+ } ) ) ,
146+ name,
147+ } ,
148+ } ) ;
149+ }
150+
151+ await mutate ( ) ;
152+
153+ setTimeout ( ( ) => {
154+ setAllowClose ( true ) ;
155+ } , 500 ) ;
156+ } ,
157+ [ tagValue , name , onChange , mutate , fetch , modals , t ]
158+ ) ;
159+
101160 return (
102161 < div
103162 ref = { ref }
@@ -122,7 +181,7 @@ export const TagsComponentInner: FC<{
122181 className = "h-full flex justify-center items-center px-[8px] rounded-[4px]"
123182 style = { { backgroundColor : tagValue [ 0 ] . color } }
124183 >
125- < span className = "mix-blend-difference text-[#fff]" >
184+ < span className = "text-shadow-tags text-[#fff]" >
126185 { tagValue [ 0 ] . name }
127186 </ span >
128187 </ div >
@@ -158,20 +217,28 @@ export const TagsComponentInner: FC<{
158217 } ) ;
159218 } }
160219 key = { p . name }
161- className = "h-[40px] py-[8px] px-[20px] -mx-[12px] flex gap-[8px]"
220+ className = "min- h-[40px] py-[8px] px-[20px] -mx-[12px] flex gap-[8px] items-center group "
162221 >
163222 < Check
164223 onChange = { ( ) => { } }
165224 value = { ! ! tagValue . find ( ( a ) => a . id === p . id ) }
166225 />
167- < div
168- className = "h-full flex justify-center items-center px-[8px] rounded-[8px]"
169- style = { { backgroundColor : p . color } }
170- >
171- < span className = "mix-blend-difference text-[#fff]" >
226+ < div className = "h-full flex items-center flex-1 break-all" >
227+ < span
228+ className = "text-[#fff] px-[8px] rounded-[8px] text-shadow-tags"
229+ style = { { backgroundColor : p . color } }
230+ >
172231 { p . name }
173232 </ span >
174233 </ div >
234+ { ! tagValue . find ( ( a ) => a . id === p . id ) && (
235+ < div
236+ onClick = { ( e ) => deleteTag ( p , e ) }
237+ className = "ms-auto transition-opacity cursor-pointer text-red-500 text-[14px] font-[600]"
238+ >
239+ ×
240+ </ div >
241+ ) }
175242 </ div >
176243 ) ) }
177244 < div
@@ -181,7 +248,9 @@ export const TagsComponentInner: FC<{
181248 < div >
182249 < PlusIcon />
183250 </ div >
184- < div className = "text-[13px] font-[600]" > { t ( 'add_new_tag' , 'Add New Tag' ) } </ div >
251+ < div className = "text-[13px] font-[600]" >
252+ { t ( 'add_new_tag' , 'Add New Tag' ) }
253+ </ div >
185254 </ div >
186255 </ div >
187256 ) }
@@ -197,7 +266,7 @@ const Check: FC<{ value: boolean; onChange: (value: boolean) => void }> = ({
197266 < div
198267 onClick = { ( ) => onChange ( ! value ) }
199268 className = { clsx (
200- 'text-[10px] font-[500] text-center flex border border-btnSimple rounded-[6px] w-[20px] h-[20px] justify-center items-center' ,
269+ 'text-[10px] font-[500] text-center flex border border-btnSimple rounded-[6px] min-w-[20px] min-h-[20px] w-[20px] h-[20px] justify-center items-center' ,
201270 value && 'bg-[#612BD3]'
202271 ) }
203272 >
@@ -403,6 +472,45 @@ export const TagsComponentA: FC<{
403472 </ >
404473 ) ;
405474} ;
475+ const ConfirmDeleteModal : FC < {
476+ tagName : string ;
477+ close : ( ) => void ;
478+ resolve : ( value : boolean ) => void ;
479+ } > = ( { tagName, close, resolve } ) => {
480+ const t = useT ( ) ;
481+
482+ return (
483+ < div className = "flex flex-col gap-[16px]" >
484+ < p className = "text-[14px]" >
485+ { t (
486+ 'confirm_delete_tag' ,
487+ 'Are you sure you want to delete the tag "{{tagName}}"?' ,
488+ { tagName }
489+ ) }
490+ </ p >
491+ < div className = "flex gap-[8px] justify-end" >
492+ < Button
493+ onClick = { ( ) => {
494+ resolve ( false ) ;
495+ close ( ) ;
496+ } }
497+ >
498+ { t ( 'cancel' , 'Cancel' ) }
499+ </ Button >
500+ < Button
501+ onClick = { ( ) => {
502+ resolve ( true ) ;
503+ close ( ) ;
504+ } }
505+ className = "bg-red-500 hover:bg-red-600"
506+ >
507+ { t ( 'delete' , 'Delete' ) }
508+ </ Button >
509+ </ div >
510+ </ div >
511+ ) ;
512+ } ;
513+
406514const ShowModal : FC < {
407515 tag : string ;
408516 color ?: string ;
0 commit comments