Skip to content

Commit 54b75e6

Browse files
authored
Refactor modal, tweak searching (#8209)
1 parent e9dea50 commit 54b75e6

2 files changed

Lines changed: 147 additions & 140 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import React from 'react'
2+
import { Modal } from '@/components/modals'
3+
import { sendRequest } from '@/utils/send-request'
4+
import { useContext, useState, useCallback } from 'react'
5+
import toast from 'react-hot-toast'
6+
import { GlossaryEntriesListContext } from '.'
7+
import { LocaleSelect } from './LocaleSelect'
8+
9+
export function ProposeTermModal({
10+
isOpen,
11+
onClose,
12+
}: {
13+
isOpen: boolean
14+
onClose: () => void
15+
}) {
16+
const { links, translationLocales } = useContext(GlossaryEntriesListContext)
17+
const [term, setTerm] = useState<string>('')
18+
const [description, setDescription] = useState<string>('')
19+
const [locale, setLocale] = useState<string>(translationLocales[0])
20+
const [translation, setTranslation] = useState<string>('')
21+
22+
const onSave = useCallback(() => {
23+
const fetch = sendRequest({
24+
endpoint: links.createGlossaryEntry,
25+
method: 'POST',
26+
body: JSON.stringify({
27+
glossary_entry: {
28+
term,
29+
llm_instructions: description,
30+
locale,
31+
translation,
32+
},
33+
}),
34+
})
35+
36+
fetch.fetch
37+
.then(() => {
38+
onClose()
39+
toast.success('Proposed a new term successfully!')
40+
})
41+
.catch((e) => {
42+
toast.error('Failed to propose a new term.', e)
43+
console.error(e)
44+
})
45+
}, [term, description, locale, translation])
46+
47+
return (
48+
<Modal open={isOpen} onClose={onClose}>
49+
<div className="w-[400px]">
50+
<h2 className="text-h2 font-bold mb-16">Propose New Term</h2>
51+
<div className="gap-16 flex flex-col">
52+
<div>
53+
<label className="block font-semibold mb-4 text-h6" htmlFor="term">
54+
Term
55+
</label>
56+
<input
57+
type="text"
58+
id="term"
59+
value={term}
60+
onChange={(e) => setTerm(e.target.value)}
61+
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
62+
placeholder="Enter term"
63+
/>
64+
65+
<p className="text-p text-textColor6 leading-130">
66+
A glossary term is a word or phrase that has a specific meaning
67+
within a particular context or field.
68+
</p>
69+
</div>
70+
<div>
71+
<label
72+
className="block font-semibold mb-4 text-h6"
73+
htmlFor="description"
74+
>
75+
Description
76+
</label>
77+
<textarea
78+
id="description"
79+
rows={4}
80+
value={description}
81+
onChange={(e) => setDescription(e.target.value)}
82+
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
83+
placeholder="Enter description"
84+
></textarea>
85+
<p className="text-p text-textColor6 leading-130">
86+
A glossary term description provides additional context or
87+
explanation about the term, helping users understand its usage and
88+
significance.
89+
</p>
90+
</div>
91+
<div>
92+
<label className="block font-semibold mb-4 text-h6">Locale</label>
93+
<LocaleSelect
94+
locales={[...(translationLocales || [])]}
95+
value={locale}
96+
onChange={(locale) => setLocale(locale)}
97+
showAll={false}
98+
label="Select locale"
99+
/>
100+
<p className="text-p text-textColor6 leading-130 mt-8">
101+
Select the language locale for this glossary term.
102+
</p>
103+
</div>
104+
<div>
105+
<label
106+
className="block font-semibold mb-4 text-h6"
107+
htmlFor="translation"
108+
>
109+
Translation
110+
</label>
111+
<input
112+
type="text"
113+
id="translation"
114+
value={translation}
115+
onChange={(e) => setTranslation(e.target.value)}
116+
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
117+
placeholder="Enter translation"
118+
/>
119+
<p className="text-p text-textColor6 leading-130">
120+
Provide the translated term or phrase in the selected locale.
121+
</p>
122+
</div>
123+
<div className="flex items-center gap-8">
124+
<button
125+
onClick={onSave}
126+
type="submit"
127+
className="btn btn-primary btn-m"
128+
>
129+
Save
130+
</button>
131+
<button
132+
type="button"
133+
className="btn btn-secondary btn-m"
134+
onClick={onClose}
135+
>
136+
Cancel
137+
</button>
138+
</div>
139+
</div>
140+
</div>
141+
</Modal>
142+
)
143+
}

app/javascript/components/localization/glossary-entries/list/Table.tsx

Lines changed: 4 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ import React, { useCallback, useContext, useEffect, useState } from 'react'
44
import { GlossaryEntriesListContext } from '.'
55
import { GlossaryEntriesTableList } from './GlossaryEntriesTableList'
66
import { Tabs } from './Tabs'
7-
import { Modal } from '@/components/modals'
8-
import { sendRequest } from '@/utils/send-request'
9-
import { Toaster, toast } from 'react-hot-toast'
7+
import { Toaster } from 'react-hot-toast'
108
import { LocaleSelect } from './LocaleSelect'
9+
import { ProposeTermModal } from './ProposeTermModal'
1110

1211
export function Table() {
13-
const { setCriteria, request, translationLocales, setQuery } =
12+
const { setCriteria, request, translationLocales, setQuery, setPage } =
1413
React.useContext(GlossaryEntriesListContext)
1514

1615
const [isOpen, setIsOpen] = React.useState(false)
@@ -25,6 +24,7 @@ export function Table() {
2524

2625
useEffect(() => {
2726
setCriteria(debouncedValue)
27+
setPage(0)
2828
}, [debouncedValue, setCriteria])
2929

3030
return (
@@ -85,139 +85,3 @@ function ProposeTermButton({ onClick }) {
8585
</button>
8686
)
8787
}
88-
89-
function ProposeTermModal({
90-
isOpen,
91-
onClose,
92-
}: {
93-
isOpen: boolean
94-
onClose: () => void
95-
}) {
96-
const { links, translationLocales } = useContext(GlossaryEntriesListContext)
97-
const [term, setTerm] = useState<string>('')
98-
const [description, setDescription] = useState<string>('')
99-
const [locale, setLocale] = useState<string>(translationLocales[0])
100-
const [translation, setTranslation] = useState<string>('')
101-
102-
const onSave = useCallback(() => {
103-
const fetch = sendRequest({
104-
endpoint: links.createGlossaryEntry,
105-
method: 'POST',
106-
body: JSON.stringify({
107-
glossary_entry: {
108-
term,
109-
llm_instructions: description,
110-
locale,
111-
translation,
112-
},
113-
}),
114-
})
115-
116-
fetch.fetch
117-
.then(() => {
118-
onClose()
119-
toast.success('Proposed a new term successfully!')
120-
})
121-
.catch((e) => {
122-
toast.error('Failed to propose a new term.', e)
123-
console.error(e)
124-
})
125-
}, [term, description, locale, translation])
126-
127-
return (
128-
<Modal open={isOpen} onClose={onClose}>
129-
<div className="w-[400px]">
130-
<h2 className="text-h2 font-bold mb-16">Propose New Term</h2>
131-
<div className="gap-16 flex flex-col">
132-
<div>
133-
<label className="block font-semibold mb-4 text-h6" htmlFor="term">
134-
Term
135-
</label>
136-
<input
137-
type="text"
138-
id="term"
139-
value={term}
140-
onChange={(e) => setTerm(e.target.value)}
141-
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
142-
placeholder="Enter term"
143-
/>
144-
145-
<p className="text-p text-textColor6 leading-130">
146-
A glossary term is a word or phrase that has a specific meaning
147-
within a particular context or field.
148-
</p>
149-
</div>
150-
<div>
151-
<label
152-
className="block font-semibold mb-4 text-h6"
153-
htmlFor="description"
154-
>
155-
Description
156-
</label>
157-
<textarea
158-
id="description"
159-
rows={4}
160-
value={description}
161-
onChange={(e) => setDescription(e.target.value)}
162-
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
163-
placeholder="Enter description"
164-
></textarea>
165-
<p className="text-p text-textColor6 leading-130">
166-
A glossary term description provides additional context or
167-
explanation about the term, helping users understand its usage and
168-
significance.
169-
</p>
170-
</div>
171-
<div>
172-
<label className="block font-semibold mb-4 text-h6">Locale</label>
173-
<LocaleSelect
174-
locales={[...(translationLocales || [])]}
175-
value={locale}
176-
onChange={(locale) => setLocale(locale)}
177-
showAll={false}
178-
label="Select locale"
179-
/>
180-
<p className="text-p text-textColor6 leading-130 mt-8">
181-
Select the language locale for this glossary term.
182-
</p>
183-
</div>
184-
<div>
185-
<label
186-
className="block font-semibold mb-4 text-h6"
187-
htmlFor="translation"
188-
>
189-
Translation
190-
</label>
191-
<input
192-
type="text"
193-
id="translation"
194-
value={translation}
195-
onChange={(e) => setTranslation(e.target.value)}
196-
className="w-full border border-gray-300 rounded px-12 py-8 mb-8"
197-
placeholder="Enter translation"
198-
/>
199-
<p className="text-p text-textColor6 leading-130">
200-
Provide the translated term or phrase in the selected locale.
201-
</p>
202-
</div>
203-
<div className="flex items-center gap-8">
204-
<button
205-
onClick={onSave}
206-
type="submit"
207-
className="btn btn-primary btn-m"
208-
>
209-
Save
210-
</button>
211-
<button
212-
type="button"
213-
className="btn btn-secondary btn-m"
214-
onClick={onClose}
215-
>
216-
Cancel
217-
</button>
218-
</div>
219-
</div>
220-
</div>
221-
</Modal>
222-
)
223-
}

0 commit comments

Comments
 (0)