@c-rex/components 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/src/autocomplete.tsx +11 -33
- package/src/dialog-filter.tsx +34 -8
- package/src/loading.tsx +12 -0
- package/src/navbar/navbar.tsx +3 -2
- package/src/navbar/search-input.tsx +16 -13
- package/src/page-wrapper.tsx +10 -3
- package/src/search-modal.tsx +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c-rex/components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"files": [
|
|
5
5
|
"src"
|
|
6
6
|
],
|
|
@@ -76,6 +76,10 @@
|
|
|
76
76
|
"./search-modal": {
|
|
77
77
|
"types": "./src/search-modal.tsx",
|
|
78
78
|
"import": "./src/search-modal.tsx"
|
|
79
|
+
},
|
|
80
|
+
"./loading": {
|
|
81
|
+
"types": "./src/loading.tsx",
|
|
82
|
+
"import": "./src/loading.tsx"
|
|
79
83
|
}
|
|
80
84
|
},
|
|
81
85
|
"scripts": {
|
package/src/autocomplete.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { Input } from "@c-rex/ui/input";
|
|
3
|
-
import { call, generateQueryParams
|
|
4
|
-
import {
|
|
3
|
+
import { call, generateQueryParams } from "@c-rex/utils";
|
|
4
|
+
import { WILD_CARD_OPTIONS } from "@c-rex/constants";
|
|
5
5
|
import { useTranslations } from "next-intl";
|
|
6
6
|
import { useAppConfig } from "@c-rex/contexts/config-provider";
|
|
7
7
|
import { QueryParams } from "@c-rex/types";
|
|
@@ -15,7 +15,7 @@ type Props = {
|
|
|
15
15
|
export const AutoComplete = ({ initialValue, embedded, searchByPackage }: Props) => {
|
|
16
16
|
const t = useTranslations();
|
|
17
17
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
18
|
-
const { contentLang, packageID } = useAppConfig()
|
|
18
|
+
const { articleLang, contentLang, packageID } = useAppConfig()
|
|
19
19
|
|
|
20
20
|
const [open, setOpen] = useState(false);
|
|
21
21
|
const [query, setQuery] = useState(initialValue);
|
|
@@ -23,43 +23,21 @@ export const AutoComplete = ({ initialValue, embedded, searchByPackage }: Props)
|
|
|
23
23
|
const [suggestions, setSuggestions] = useState<string[]>([]);
|
|
24
24
|
|
|
25
25
|
const onSearch = (value: string): Promise<string[]> => {
|
|
26
|
-
return call<string[]>("InformationUnitsService.getSuggestions", { query: value, language: contentLang });
|
|
26
|
+
return call<string[]>("InformationUnitsService.getSuggestions", { query: value, language: articleLang || contentLang });
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const onSelect = (value: string) => {
|
|
30
|
-
const cookie = getFromCookieString(document.cookie, CONTENT_LANG_KEY)
|
|
31
30
|
const params: QueryParams[] = [
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
value: "OR"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
key: "page",
|
|
42
|
-
value: "1"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
key: "language",
|
|
46
|
-
value: cookie
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
key: "wildcard",
|
|
50
|
-
value: WILD_CARD_OPTIONS.BOTH
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
key: "like",
|
|
54
|
-
value: "false"
|
|
55
|
-
},
|
|
31
|
+
{ key: "search", value: value },
|
|
32
|
+
{ key: "operator", value: "OR" },
|
|
33
|
+
{ key: "page", value: "1" },
|
|
34
|
+
{ key: "language", value: articleLang || contentLang as string },
|
|
35
|
+
{ key: "wildcard", value: WILD_CARD_OPTIONS.BOTH },
|
|
36
|
+
{ key: "like", value: "false" },
|
|
56
37
|
]
|
|
57
38
|
|
|
58
39
|
if (searchByPackage && packageID !== null) {
|
|
59
|
-
params.push({
|
|
60
|
-
key: "package",
|
|
61
|
-
value: packageID
|
|
62
|
-
})
|
|
40
|
+
params.push({ key: "packages", value: packageID })
|
|
63
41
|
}
|
|
64
42
|
|
|
65
43
|
const aux = generateQueryParams(params)
|
package/src/dialog-filter.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC, useState } from "react"
|
|
1
|
+
import React, { FC, use, useEffect, useState } from "react"
|
|
2
2
|
import { Button } from "@c-rex/ui/button"
|
|
3
3
|
import {
|
|
4
4
|
Dialog,
|
|
@@ -10,8 +10,6 @@ import {
|
|
|
10
10
|
DialogTrigger,
|
|
11
11
|
} from "@c-rex/ui/dialog"
|
|
12
12
|
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@c-rex/ui/select"
|
|
13
|
-
import { ToggleGroup, ToggleGroupItem } from "@c-rex/ui/toggle-group"
|
|
14
|
-
import { RadioGroup, RadioGroupItem } from "@c-rex/ui/radio-group"
|
|
15
13
|
import { Checkbox } from "@c-rex/ui/checkbox"
|
|
16
14
|
import { Label } from "@c-rex/ui/label"
|
|
17
15
|
import { parseAsBoolean, parseAsInteger, parseAsString, useQueryStates } from "nuqs"
|
|
@@ -23,6 +21,7 @@ import { Switch } from "@c-rex/ui/switch"
|
|
|
23
21
|
|
|
24
22
|
interface DialogFilterProps {
|
|
25
23
|
trigger: React.ReactNode;
|
|
24
|
+
setLoading: (loading: boolean) => void;
|
|
26
25
|
}
|
|
27
26
|
interface Languages {
|
|
28
27
|
lang: string;
|
|
@@ -30,7 +29,7 @@ interface Languages {
|
|
|
30
29
|
checked: boolean;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
32
|
+
export const DialogFilter: FC<DialogFilterProps> = ({ trigger, setLoading }) => {
|
|
34
33
|
const t = useTranslations("filter");
|
|
35
34
|
const { availableLanguagesAndCountries } = useAppConfig()
|
|
36
35
|
const [params, setParams] = useQueryStates({
|
|
@@ -38,6 +37,7 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
38
37
|
page: parseAsInteger,
|
|
39
38
|
wildcard: parseAsString,
|
|
40
39
|
operator: parseAsString,
|
|
40
|
+
filter: parseAsString,
|
|
41
41
|
like: parseAsBoolean,
|
|
42
42
|
}, {
|
|
43
43
|
history: 'push',
|
|
@@ -49,6 +49,7 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
49
49
|
const [operator, setOperator] = useState<string>(params.operator || OPERATOR_OPTIONS.OR);
|
|
50
50
|
const [like, setLike] = useState<boolean>(params.like || false);
|
|
51
51
|
const [wildcard, setWildcard] = useState<string>(params.wildcard || "");
|
|
52
|
+
const [disabled, setDisabled] = useState<boolean>(false)
|
|
52
53
|
const [languages, setLanguages] = useState<Languages[]>(availableLanguagesAndCountries.map((item: LanguageAndCountries) => {
|
|
53
54
|
const checked = startSelectedLanguages.includes(item.value)
|
|
54
55
|
|
|
@@ -68,7 +69,12 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
const apply = () => {
|
|
71
|
-
|
|
72
|
+
setLoading(true);
|
|
73
|
+
|
|
74
|
+
const selectedLanguages = languages
|
|
75
|
+
.filter((item: any) => item.checked)
|
|
76
|
+
.map((item: any) => item.value)
|
|
77
|
+
.join(',')
|
|
72
78
|
|
|
73
79
|
setParams({
|
|
74
80
|
page: 1,
|
|
@@ -76,9 +82,29 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
76
82
|
operator: operator,
|
|
77
83
|
wildcard: wildcard,
|
|
78
84
|
like: like,
|
|
85
|
+
filter: null,
|
|
79
86
|
});
|
|
80
87
|
}
|
|
81
88
|
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
setOperator(params.operator || OPERATOR_OPTIONS.OR);
|
|
91
|
+
setLike(params.like || false);
|
|
92
|
+
setWildcard(params.wildcard || "");
|
|
93
|
+
setLanguages(availableLanguagesAndCountries.map((item: LanguageAndCountries) => {
|
|
94
|
+
const checked = startSelectedLanguages.includes(item.value)
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
lang: item.lang,
|
|
98
|
+
value: item.value,
|
|
99
|
+
checked,
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
}, [params])
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
setDisabled(languages.every((item) => !item.checked));
|
|
106
|
+
}, [languages])
|
|
107
|
+
|
|
82
108
|
return (
|
|
83
109
|
<Dialog>
|
|
84
110
|
<DialogTrigger asChild>
|
|
@@ -143,12 +169,12 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
143
169
|
</div>
|
|
144
170
|
|
|
145
171
|
<div className="grid grid-cols-2 items-center pt-2">
|
|
146
|
-
<Label className="text-right">
|
|
172
|
+
<Label htmlFor="operator" className="text-right">
|
|
147
173
|
{t("operator")}:
|
|
148
174
|
</Label>
|
|
149
175
|
|
|
150
176
|
<Switch
|
|
151
|
-
id="
|
|
177
|
+
id="operator"
|
|
152
178
|
onCheckedChange={(value) => setOperator(value ? OPERATOR_OPTIONS.AND : OPERATOR_OPTIONS.OR)}
|
|
153
179
|
checked={operator == OPERATOR_OPTIONS.AND}
|
|
154
180
|
/>
|
|
@@ -163,7 +189,7 @@ export const DialogFilter: FC<DialogFilterProps> = ({ trigger }) => {
|
|
|
163
189
|
|
|
164
190
|
<DialogFooter className="pt-2">
|
|
165
191
|
<DialogClose asChild>
|
|
166
|
-
<Button onClick={apply}>{t("apply")}</Button>
|
|
192
|
+
<Button onClick={apply} disabled={disabled}>{t("apply")}</Button>
|
|
167
193
|
</DialogClose>
|
|
168
194
|
</DialogFooter>
|
|
169
195
|
</DialogContent>
|
package/src/loading.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { FC } from "react";
|
|
2
|
+
|
|
3
|
+
type LoadingProps = {
|
|
4
|
+
opacity: boolean;
|
|
5
|
+
}
|
|
6
|
+
export const Loading: FC<LoadingProps> = ({ opacity }) => {
|
|
7
|
+
return (
|
|
8
|
+
<div className={`fixed inset-0 z-[100000] w-full h-full flex justify-center items-center bg-white ${opacity ? "opacity-50" : ""}`}>
|
|
9
|
+
<div className="animate-spin rounded-full h-12 w-12 border-2 border-gray-300 border-t-gray-950"></div>
|
|
10
|
+
</div>
|
|
11
|
+
);
|
|
12
|
+
};
|
package/src/navbar/navbar.tsx
CHANGED
|
@@ -11,9 +11,10 @@ import { SearchInput } from "./search-input";
|
|
|
11
11
|
interface NavBarProps {
|
|
12
12
|
title: string;
|
|
13
13
|
showInput: boolean;
|
|
14
|
+
showPkgFilter: boolean;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
export const NavBar: FC<NavBarProps> = async ({ title, showInput }) => {
|
|
17
|
+
export const NavBar: FC<NavBarProps> = async ({ title, showInput, showPkgFilter }) => {
|
|
17
18
|
const configs = await getConfigs();
|
|
18
19
|
|
|
19
20
|
let session: any;
|
|
@@ -42,7 +43,7 @@ export const NavBar: FC<NavBarProps> = async ({ title, showInput }) => {
|
|
|
42
43
|
</div>
|
|
43
44
|
|
|
44
45
|
<div className="flex items-center space-x-3">
|
|
45
|
-
<SearchInput showInput={showInput} />
|
|
46
|
+
<SearchInput showInput={showInput} showPkgFilter={showPkgFilter} />
|
|
46
47
|
|
|
47
48
|
{configs.OIDC.user.enabled && (
|
|
48
49
|
<>
|
|
@@ -7,9 +7,10 @@ import { AutoComplete } from "../autocomplete";
|
|
|
7
7
|
|
|
8
8
|
type Props = {
|
|
9
9
|
showInput: boolean
|
|
10
|
+
showPkgFilter: boolean
|
|
10
11
|
}
|
|
11
|
-
export const SearchInput: FC<Props> = ({ showInput }) => {
|
|
12
|
-
const [checked, setChecked] = useState<boolean>(
|
|
12
|
+
export const SearchInput: FC<Props> = ({ showInput, showPkgFilter }) => {
|
|
13
|
+
const [checked, setChecked] = useState<boolean>(true);
|
|
13
14
|
|
|
14
15
|
if (!showInput) {
|
|
15
16
|
return null;
|
|
@@ -25,17 +26,19 @@ export const SearchInput: FC<Props> = ({ showInput }) => {
|
|
|
25
26
|
searchByPackage={checked}
|
|
26
27
|
/>
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
<
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
{showPkgFilter && <>
|
|
30
|
+
<TooltipProvider>
|
|
31
|
+
<Tooltip delayDuration={100}>
|
|
32
|
+
<TooltipTrigger onClick={() => setChecked(!checked)}>
|
|
33
|
+
{checked ? <FileCheck className="opacity-50" /> : <FileX className="opacity-50" />}
|
|
34
|
+
</TooltipTrigger>
|
|
35
|
+
|
|
36
|
+
<TooltipContent>
|
|
37
|
+
If checked will search only in this document
|
|
38
|
+
</TooltipContent>
|
|
39
|
+
</Tooltip>
|
|
40
|
+
</TooltipProvider>
|
|
41
|
+
</>}
|
|
39
42
|
|
|
40
43
|
</div>
|
|
41
44
|
);
|
package/src/page-wrapper.tsx
CHANGED
|
@@ -4,13 +4,20 @@ import { NavBar } from './navbar/navbar';
|
|
|
4
4
|
type Props = {
|
|
5
5
|
children: React.ReactNode;
|
|
6
6
|
title: string;
|
|
7
|
-
|
|
7
|
+
pageType: "BLOG" | "DOC" | "HOME"
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const PageWrapper = ({ children, title,
|
|
10
|
+
export const PageWrapper = ({ children, title, pageType }: Props) => {
|
|
11
|
+
const showInput = pageType === "DOC" || pageType === "BLOG"
|
|
12
|
+
const showPkgFilter = pageType === "DOC"
|
|
13
|
+
|
|
11
14
|
return (
|
|
12
15
|
<>
|
|
13
|
-
<NavBar
|
|
16
|
+
<NavBar
|
|
17
|
+
title={title}
|
|
18
|
+
showInput={showInput}
|
|
19
|
+
showPkgFilter={showPkgFilter}
|
|
20
|
+
/>
|
|
14
21
|
{children}
|
|
15
22
|
</>
|
|
16
23
|
);
|
package/src/search-modal.tsx
CHANGED
|
@@ -38,7 +38,7 @@ export const SearchModal: FC<SearchModalProps> = ({ trigger }) => {
|
|
|
38
38
|
wildcard: parseAsString,
|
|
39
39
|
operator: parseAsString,
|
|
40
40
|
search: parseAsString,
|
|
41
|
-
|
|
41
|
+
packages: parseAsString,
|
|
42
42
|
tags: parseAsBoolean,
|
|
43
43
|
like: parseAsBoolean,
|
|
44
44
|
}, {
|
|
@@ -80,7 +80,6 @@ export const SearchModal: FC<SearchModalProps> = ({ trigger }) => {
|
|
|
80
80
|
wildcard: WILD_CARD_OPTIONS.BOTH,
|
|
81
81
|
tags: false,
|
|
82
82
|
like: false,
|
|
83
|
-
package: ""
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
|