@rpcbase/client 0.227.0 → 0.231.0
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 +11 -113
- package/src/apiClient/getServerApiClient.ts +131 -0
- package/src/apiClient/index.ts +86 -0
- package/src/index.ts +3 -0
- package/src/initClient.ts +32 -0
- package/src/types.ts +7 -0
- package/AppProvider/AnalyticsContainer.js +0 -56
- package/AppProvider/debug.js +0 -4
- package/AppProvider/index.tsx +0 -79
- package/access-control/ACLForm/components/GrantField/OpSelector.tsx +0 -129
- package/access-control/ACLForm/components/GrantField/ResourceSelector.tsx +0 -86
- package/access-control/ACLForm/components/GrantField/UsersSelector.tsx +0 -96
- package/access-control/ACLForm/components/GrantField/grant-field.scss +0 -26
- package/access-control/ACLForm/components/GrantField/icons/CheckMark.tsx +0 -16
- package/access-control/ACLForm/components/GrantField/icons/CollapseArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/icons/ExpandArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/index.tsx +0 -91
- package/access-control/ACLForm/components/GrantsList.tsx +0 -48
- package/access-control/ACLForm/components/RoleForm.tsx +0 -134
- package/access-control/ACLForm/components/RoleView.tsx +0 -115
- package/access-control/ACLForm/components/RolesList.tsx +0 -79
- package/access-control/ACLForm/components/constants.tsx +0 -1
- package/access-control/ACLForm/components/resolver.ts +0 -57
- package/access-control/ACLForm/components/role-form.scss +0 -19
- package/access-control/ACLForm/index.tsx +0 -48
- package/access-control/ACLModal/acl-modal.scss +0 -7
- package/access-control/ACLModal/index.tsx +0 -66
- package/access-control/PolicyEditor/TargetSelector/QueryBuilder.tsx +0 -48
- package/access-control/PolicyEditor/TargetSelector/index.tsx +0 -5
- package/access-control/PolicyEditor/TargetSelector/query-builder.scss +0 -9
- package/access-control/PolicyEditor/index.tsx +0 -165
- package/access-control/index.ts +0 -3
- package/apiClient.js +0 -15
- package/auth/authProps.js +0 -8
- package/auth/components/AccountsList/AccountListItem.js +0 -61
- package/auth/components/AccountsList/account-list-item.scss +0 -5
- package/auth/components/AccountsList/index.js +0 -17
- package/auth/components/Footer/index.js +0 -11
- package/auth/components/ForgotPassword/forgot-password.scss +0 -37
- package/auth/components/ForgotPassword/index.js +0 -114
- package/auth/components/SetNewPassword/index.js +0 -130
- package/auth/components/SetNewPassword/set-new-password.scss +0 -47
- package/auth/components/SignIn/SignInEmailForm.tsx +0 -115
- package/auth/components/SignIn/index.js +0 -69
- package/auth/components/SignIn/sign-in.scss +0 -56
- package/auth/components/SignOut/index.js +0 -144
- package/auth/components/SignOut/sign-out.scss +0 -34
- package/auth/components/SignUp/SignUpEmailForm.tsx +0 -98
- package/auth/components/SignUp/index.js +0 -66
- package/auth/components/SignUp/sign-up.scss +0 -56
- package/auth/getTenantId.js +0 -12
- package/auth/getUid.js +0 -11
- package/auth/helpers/redirectSignIn.native.js +0 -9
- package/auth/helpers/redirectSignIn.web.js +0 -7
- package/auth/index.js +0 -146
- package/auth/signOut.js +0 -20
- package/auth/useAuthRouter.js +0 -56
- package/env.d.ts +0 -3
- package/firebase/index.js +0 -1
- package/firebase/sw.js +0 -1
- package/form/FileInput/FileUploadContext.tsx +0 -162
- package/form/FileInput/FileUploadForm/index.tsx +0 -139
- package/form/FileInput/FileUploadForm/usePreventUnload.js +0 -21
- package/form/FileInput/UploadButton.tsx +0 -23
- package/form/FileInput/constants.ts +0 -16
- package/form/FileInput/file-input.scss +0 -1
- package/form/FileInput/index.tsx +0 -21
- package/form/FileInput/upload-worker/get_file_hash.js +0 -63
- package/form/FileInput/upload-worker/index.js +0 -16
- package/form/FileInput/upload-worker/no_compress_exts.ts +0 -33
- package/form/FileInput/upload-worker/upload_file.js +0 -129
- package/form/Form.tsx +0 -23
- package/form/Input.tsx +0 -62
- package/form/SubmitButton/index.tsx +0 -58
- package/form/hook-form.tsx +0 -7
- package/form/index.tsx +0 -5
- package/getBaseUrl.js +0 -14
- package/getObjectId.ts +0 -31
- package/hashState.js +0 -158
- package/helpers/createBatcher/index.js +0 -36
- package/helpers/getInitials.js +0 -39
- package/helpers/onReady.js +0 -15
- package/helpers/post.js +0 -18
- package/helpers/postRPC.js +0 -42
- package/helpers/useRPC.js +0 -41
- package/helpers/useStoredValue/batchedGetStoredValues.js +0 -30
- package/helpers/useStoredValue/index.js +0 -107
- package/helpers/useStoredValue/setStoredValues.js +0 -14
- package/i18n/en/rb.nav.json +0 -13
- package/i18n/en/rb.sign_in.json +0 -11
- package/i18n/en/rb.sign_out.json +0 -5
- package/i18n/fr/rb.sign_in.json +0 -11
- package/i18n/fr/rb.sign_out.json +0 -5
- package/i18n/index.js +0 -63
- package/index.js +0 -6
- package/isEqualValues.js +0 -47
- package/jest.config.js +0 -16
- package/notifications/Notification/index.js +0 -36
- package/notifications/Notification/notification.scss +0 -1
- package/notifications/NotificationItem/HeaderStatus.js +0 -93
- package/notifications/NotificationItem/index.js +0 -65
- package/notifications/NotificationItem/notification-item.scss +0 -25
- package/notifications/NotificationsContainer/index.js +0 -37
- package/notifications/NotificationsContainer/notifications-container.scss +0 -38
- package/notifications/NotificationsContainer/useLLTs.js +0 -28
- package/notifications/NotificationsContext/index.js +0 -71
- package/notifications/NotificationsContext/useNotificationsList.js +0 -75
- package/notifications/NotificationsSettingsModal/SettingsForm.js +0 -52
- package/notifications/NotificationsSettingsModal/index.js +0 -48
- package/notifications/NotificationsSettingsModal/notifications-settings.scss +0 -1
- package/notifications/config.js +0 -1
- package/notifications/index.js +0 -4
- package/page.js +0 -9
- package/publish-output.txt +0 -0
- package/rpc.js +0 -32
- package/rr-trace/get_fingerprint.js +0 -10
- package/rr-trace/get_perf_vitals.js +0 -24
- package/rr-trace/get_session_id.js +0 -29
- package/rr-trace/index.js +0 -138
- package/rr-trace/write_session_data.js +0 -86
- package/rts/boot.js +0 -3
- package/rts/getUseDocument.js +0 -21
- package/rts/getUseQuery/index.js +0 -233
- package/rts/getUseQuery/useData.js +0 -55
- package/rts/index.js +0 -10
- package/rts/rts.js +0 -243
- package/rts/signout.ts +0 -8
- package/rts/store/constants.js +0 -3
- package/rts/store/debug.js +0 -24
- package/rts/store/get_collection.js +0 -55
- package/rts/store/index.js +0 -100
- package/rts/store/replace_query_keys.js +0 -30
- package/rts/store/satisfies_projection.js +0 -32
- package/rts/store/update_docs.js +0 -47
- package/storage/index.jest.js +0 -15
- package/storage/index.native.js +0 -38
- package/storage/index.web.js +0 -25
- package/types.ts +0 -6
- package/ui/ActivityIndicator/index.js +0 -113
- package/ui/Avatar/index.native.js +0 -31
- package/ui/Avatar/index.web.js +0 -37
- package/ui/Avatar/styles.js +0 -41
- package/ui/ErrorBoundary/index.js +0 -12
- package/ui/ExpandableFloatView/exp.scss +0 -15
- package/ui/ExpandableFloatView/index.tsx +0 -123
- package/ui/ExpandableFloatView/useBackdrop.js +0 -45
- package/ui/LottiePlayer/LottiePlayer.js +0 -4
- package/ui/LottiePlayer/index.js +0 -8
- package/ui/Modal/HashStateModal.js +0 -30
- package/ui/Modal/Modal.js +0 -93
- package/ui/Modal/ModalForm/AlertBanner.js +0 -82
- package/ui/Modal/ModalForm/index.js +0 -188
- package/ui/Modal/ModalForm/modal-form.scss +0 -63
- package/ui/Modal/index.js +0 -10
- package/ui/Modal/modal.scss +0 -101
- package/ui/Modal/withHashStateModal.js +0 -24
- package/ui/RedboxError/index.js +0 -3
- package/ui/Search/SearchHistory/index.js +0 -45
- package/ui/Search/SearchHistory/search-history.scss +0 -9
- package/ui/Search/SearchHistory/useSearchHistory.tsx +0 -57
- package/ui/Search/SearchResults/index.tsx +0 -90
- package/ui/Search/index.tsx +0 -298
- package/ui/Search/search.scss +0 -0
- package/ui/SelectPills/index.tsx +0 -96
- package/ui/SelectPills/select-pills.scss +0 -66
- package/ui/Tabs/index.tsx +0 -161
- package/ui/Tabs/tabs.scss +0 -53
- package/ui/Tree/index.js +0 -257
- package/ui/Tree/model.js +0 -71
- package/ui/Tree/node.js +0 -112
- package/ui/Tree/tree.scss +0 -98
- package/ui/UserAvatar/default_colors.json +0 -82
- package/ui/UserAvatar/index.js +0 -55
- package/ui/View/index.tsx +0 -17
- package/ui/View/index.web.js +0 -44
- package/ui/animations/checkmark.json +0 -1
- package/ui/helpers/SizeContext/index.tsx +0 -11
- package/ui/helpers/helpers.scss +0 -61
- package/ui/helpers/index.ts +0 -6
- package/ui/helpers/stopEventPropagation.js +0 -5
- package/ui/helpers/useActiveListItemIndex/index.tsx +0 -45
- package/ui/helpers/useScrollSelectorIntoView/index.tsx +0 -14
- package/ui/helpers/useThrottledMeasure/index.js +0 -47
- package/ui/helpers/withSuspense/index.js +0 -37
- package/ui/icons/AddAccount.tsx +0 -5
- package/ui/icons/Billing.tsx +0 -6
- package/ui/icons/Close.tsx +0 -14
- package/ui/icons/Organization.tsx +0 -5
- package/ui/icons/Signout.tsx +0 -5
- package/ui/icons/index.tsx +0 -6
- package/ui/nav/AccountsDropdown/SwitchAccounts.tsx +0 -28
- package/ui/nav/AccountsDropdown/accounts-dropdown.scss +0 -51
- package/ui/nav/AccountsDropdown/index.tsx +0 -90
- package/ui/nav/AccountsToggle/index.tsx +0 -24
- package/ui/nav/ContentView/ContentViewContext.ts +0 -23
- package/ui/nav/ContentView/index.tsx +0 -115
- package/ui/nav/HeaderContainer/header.scss +0 -52
- package/ui/nav/HeaderContainer/index.tsx +0 -23
- package/ui/nav/HeaderContainer/variables.scss +0 -1
- package/ui/nav/MorphingDropdown/MorphingDropdownContext.tsx +0 -151
- package/ui/nav/MorphingDropdown/MorphingDropdownMenu.tsx +0 -38
- package/ui/nav/MorphingDropdown/MorphingDropdownPortal.tsx +0 -166
- package/ui/nav/MorphingDropdown/MorphingDropdownToggle.tsx +0 -34
- package/ui/nav/MorphingDropdown/index.tsx +0 -16
- package/ui/nav/MorphingDropdown/morphing-dropdown.scss +0 -35
- package/ui/nav/NotificationsDropdown/index.tsx +0 -52
- package/ui/nav/NotificationsDropdown/notifications-dropdown.scss +0 -5
- package/ui/nav/NotificationsToggle/NotificationsGlyph.tsx +0 -54
- package/ui/nav/NotificationsToggle/index.tsx +0 -12
- package/ui/nav/NotificationsToggle/notification-animation.json +0 -1
- package/ui/nav/NotificationsToggle/notifications-toggle.scss +0 -26
- package/ui/nav/SidebarContainer/index.tsx +0 -48
- package/ui/nav/SidebarContainer/sidebar-container.scss +0 -21
- package/ui/nav/SlideoutContainer/components/Body.tsx +0 -19
- package/ui/nav/SlideoutContainer/components/Header.tsx +0 -23
- package/ui/nav/SlideoutContainer/components/Wrapper.tsx +0 -46
- package/ui/nav/SlideoutContainer/index.tsx +0 -50
- package/ui/nav/SlideoutContainer/slideout-container.scss +0 -40
- package/ui/nav/index.ts +0 -13
- package/ui/oauth/GitHub.js +0 -38
- package/ui/oauth/getGitHubSigninUrl.js +0 -30
- package/ui/oauth/index.js +0 -9
- package/ui/oauth/oauth.scss +0 -16
- package/ui/sortable-hoc/AutoScroller.js +0 -76
- package/ui/sortable-hoc/DragHandle.js +0 -31
- package/ui/sortable-hoc/Manager.js +0 -54
- package/ui/sortable-hoc/README.md +0 -1
- package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +0 -7
- package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +0 -24
- package/ui/sortable-hoc/SortableContainer/index.js +0 -994
- package/ui/sortable-hoc/SortableContainer/props.js +0 -81
- package/ui/sortable-hoc/SortableElement.js +0 -111
- package/ui/sortable-hoc/SortableHandle.js +0 -45
- package/ui/sortable-hoc/drag-handle.scss +0 -14
- package/ui/sortable-hoc/index.js +0 -9
- package/ui/sortable-hoc/utils.js +0 -292
- package/ui/springs.ts +0 -17
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import {useEffect, useState} from "react"
|
|
3
|
-
|
|
4
|
-
import {useQuery} from "@rpcbase/client/rts"
|
|
5
|
-
import {getUid} from "@rpcbase/client/auth/getUid"
|
|
6
|
-
|
|
7
|
-
import stripDiacritics from "react-bootstrap-typeahead/cjs/utils/stripDiacritics"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const HISTORY_MAX_RESULTS = 10
|
|
11
|
-
|
|
12
|
-
export const useSearchHistory = () => {
|
|
13
|
-
const user_id = getUid()
|
|
14
|
-
|
|
15
|
-
const [history, setHistory] = useState([])
|
|
16
|
-
const historyQuery = useQuery("SearchHistory", {_owners: {$in: [user_id]}})
|
|
17
|
-
|
|
18
|
-
// Initial load history
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
if (!historyQuery.data) return
|
|
21
|
-
|
|
22
|
-
// map sorted items
|
|
23
|
-
const sorted_items = historyQuery.data
|
|
24
|
-
.filter((item) => !!item.data)
|
|
25
|
-
.sort((a, b) => new Date(b._created_at) - new Date(a._created_at))
|
|
26
|
-
.map((item) => {
|
|
27
|
-
const query = item.data.query
|
|
28
|
-
return {
|
|
29
|
-
query,
|
|
30
|
-
query_key: stripDiacritics(query.toLowerCase()),
|
|
31
|
-
timestamp: new Date(item._created_at),
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
// add values and check for unicity
|
|
36
|
-
const results = []
|
|
37
|
-
for (let i = 0; i < sorted_items.length; i++) {
|
|
38
|
-
// stop if we have reached results limit
|
|
39
|
-
if (results.length > HISTORY_MAX_RESULTS) {
|
|
40
|
-
break
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const item = sorted_items[i]
|
|
44
|
-
|
|
45
|
-
// before inserting into results, check if there is another occurrence in results
|
|
46
|
-
if (results.find((o) => o.query_key === item.query_key)) {
|
|
47
|
-
continue
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
results.push(item)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
setHistory(results)
|
|
54
|
-
}, [historyQuery.data, setHistory])
|
|
55
|
-
|
|
56
|
-
return history
|
|
57
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import _pick from "lodash/pick"
|
|
2
|
-
import _snakeCase from "lodash/snakeCase"
|
|
3
|
-
|
|
4
|
-
import {useHashState} from "../../../hashState"
|
|
5
|
-
|
|
6
|
-
import {useActiveListItemIndex} from "../../helpers/useActiveListItemIndex"
|
|
7
|
-
import {useScrollSelectorIntoView} from "../../helpers/useScrollSelectorIntoView"
|
|
8
|
-
|
|
9
|
-
// import save_search from "rpc!server/search-indexer/save_search"
|
|
10
|
-
|
|
11
|
-
export const SearchResults = ({
|
|
12
|
-
id = "search-results",
|
|
13
|
-
query,
|
|
14
|
-
results,
|
|
15
|
-
searchContext,
|
|
16
|
-
onCompleteSearch,
|
|
17
|
-
children,
|
|
18
|
-
renderResultItem,
|
|
19
|
-
}) => {
|
|
20
|
-
const {serializeHashState} = useHashState()
|
|
21
|
-
|
|
22
|
-
const getItemId = (i) => `${id}-result-${i}`
|
|
23
|
-
|
|
24
|
-
const getLink = (item) =>{
|
|
25
|
-
return `#${_snakeCase(item)}`
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const onSelectItem = (selectedIndex) => {
|
|
29
|
-
// console.log("ON SELEC", selectedIndex)
|
|
30
|
-
serializeHashState({link: getLink(results[selectedIndex])})
|
|
31
|
-
// if (window)
|
|
32
|
-
|
|
33
|
-
onCompleteSearch()
|
|
34
|
-
// go to selected item
|
|
35
|
-
// const targetItem = items[selectedIndex]
|
|
36
|
-
// applyTargetItem(targetItem)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const {activeItemIndex} = useActiveListItemIndex({items: results, onSelectItem})
|
|
40
|
-
|
|
41
|
-
useScrollSelectorIntoView(`#${getItemId(activeItemIndex)}`)
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<div>
|
|
45
|
-
<div className="list-group list-group-flush">
|
|
46
|
-
{results.map((item: any, index: number) => {
|
|
47
|
-
|
|
48
|
-
const key = getItemId(index)
|
|
49
|
-
|
|
50
|
-
const onClick = () => {
|
|
51
|
-
onSelectItem(index)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<a
|
|
56
|
-
id={key}
|
|
57
|
-
key={key}
|
|
58
|
-
className={cx(
|
|
59
|
-
"list-group-item list-group-item-action d-flex justify-content-between align-items-start",
|
|
60
|
-
{active: activeItemIndex === index},
|
|
61
|
-
)}
|
|
62
|
-
href={getLink(item)}
|
|
63
|
-
onClick={onClick}
|
|
64
|
-
>
|
|
65
|
-
<div className="ms-2 me-auto">
|
|
66
|
-
{renderResultItem(item, index)}
|
|
67
|
-
{/* {Object.keys(item.highlight).map((highlightKey, j) => (
|
|
68
|
-
<div
|
|
69
|
-
key={`highlight-${j}`}
|
|
70
|
-
className="item-highlight"
|
|
71
|
-
dangerouslySetInnerHTML={{__html: item.highlight[highlightKey][0]}}
|
|
72
|
-
/>
|
|
73
|
-
))} */}
|
|
74
|
-
<small className="fst-italic">{"displaySub"}</small>
|
|
75
|
-
</div>
|
|
76
|
-
{/* <span className="badge text-bg-light rounded-pill">
|
|
77
|
-
{item.fuzzy_score?.toFixed(2)}
|
|
78
|
-
</span> */}
|
|
79
|
-
{/* <span className="badge bg-primary rounded-pill">{item._score.toFixed(2)}</span> */}
|
|
80
|
-
</a>
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
})}
|
|
84
|
-
|
|
85
|
-
{/* children can be components like search history, etc */}
|
|
86
|
-
{children}
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
)
|
|
90
|
-
}
|
package/ui/Search/index.tsx
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
import assert from "assert"
|
|
2
|
-
import {ReactNode, useEffect, useState, useRef, useCallback} from "react"
|
|
3
|
-
import {Typeahead} from "react-bootstrap-typeahead"
|
|
4
|
-
import Overlay from "react-bootstrap/Overlay"
|
|
5
|
-
import _throttle from "lodash/throttle"
|
|
6
|
-
|
|
7
|
-
import ActivityIndicator from "../ActivityIndicator"
|
|
8
|
-
|
|
9
|
-
// import ItemContext from "helpers/ItemContext"
|
|
10
|
-
// import {useEnvContext} from "helpers/EnvContext"
|
|
11
|
-
|
|
12
|
-
import {SearchResults} from "./SearchResults"
|
|
13
|
-
import {SearchHistory} from "./SearchHistory"
|
|
14
|
-
|
|
15
|
-
// import search_anything from "rpc!server/search-indexer/search_anything"
|
|
16
|
-
// import search_advanced from "rpc!server/search-indexer/advanced/search_advanced"
|
|
17
|
-
// import get_item_info from "rpc!server/items/get_item_info"
|
|
18
|
-
|
|
19
|
-
import "./search.scss"
|
|
20
|
-
|
|
21
|
-
// import stripDiacritics from "react-bootstrap-typeahead/cjs/utils/stripDiacritics"
|
|
22
|
-
// TODO: at this point we don't use any rbt features, it's best to remove it from here
|
|
23
|
-
// and reimplement the token + input rendering ourselves
|
|
24
|
-
|
|
25
|
-
const MIN_SEARCH_LENGTH = 2
|
|
26
|
-
// TODO: i18n placeholder
|
|
27
|
-
const PLACEHOLDER = "Search..."
|
|
28
|
-
|
|
29
|
-
export const Search = ({
|
|
30
|
-
id = "search-input",
|
|
31
|
-
minLength = MIN_SEARCH_LENGTH,
|
|
32
|
-
onSearch,
|
|
33
|
-
renderResultItem,
|
|
34
|
-
}: {
|
|
35
|
-
id?: string,
|
|
36
|
-
minLength?: number
|
|
37
|
-
onSearch: (queryStr: string) => Promise<Array<any>>
|
|
38
|
-
renderResultItem: (item: any, index: number) => ReactNode
|
|
39
|
-
}) => {
|
|
40
|
-
// const envContext = useEnvContext()
|
|
41
|
-
// const itemContext = useContext(ItemContext)
|
|
42
|
-
const typeaheadRef = useRef()
|
|
43
|
-
const wrapperRef = useRef()
|
|
44
|
-
|
|
45
|
-
const [results, setResults] = useState<Array<any>>([])
|
|
46
|
-
const [isLoading, setIsLoading] = useState(false)
|
|
47
|
-
const [isFocused, setIsFocused] = useState(false)
|
|
48
|
-
const [showResults, setShowResults] = useState(false)
|
|
49
|
-
const [currentInputValue, setCurrentInputValue] = useState("")
|
|
50
|
-
|
|
51
|
-
const [selected, setSelected] = useState([{id: null, name: ""}])
|
|
52
|
-
|
|
53
|
-
const onShortcutToggle = () => {
|
|
54
|
-
if (!showResults) {
|
|
55
|
-
typeaheadRef.current?.focus()
|
|
56
|
-
}
|
|
57
|
-
if (showResults) {
|
|
58
|
-
setShowResults(false)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
// this event triggerred from hot keys in router as it must be a global listener
|
|
64
|
-
document.body.addEventListener("toggle-search-anything", onShortcutToggle)
|
|
65
|
-
|
|
66
|
-
return () => document.body.removeEventListener("toggle-search-anything", onShortcutToggle)
|
|
67
|
-
}, [])
|
|
68
|
-
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
// TODO: do not load if name in cache?
|
|
71
|
-
// TODO: reapply selection when navigation changes
|
|
72
|
-
// if (itemContext.id && selected.length > 0 && itemContext.id !== selected[0]?.id) {
|
|
73
|
-
// const load = async() => {
|
|
74
|
-
// const res = await get_item_info({id: itemContext.id, col: itemContext.col})
|
|
75
|
-
// assert(res.status === "ok")
|
|
76
|
-
// setSelected([{id: itemContext.id, col: itemContext.col, name: res.name}])
|
|
77
|
-
// }
|
|
78
|
-
// load()
|
|
79
|
-
// }
|
|
80
|
-
// }, [itemContext, selected, setSelected])
|
|
81
|
-
}, [])
|
|
82
|
-
|
|
83
|
-
const onFocus = (e: SyntheticFocusEvent<HTMLElement>) => {
|
|
84
|
-
setShowResults(true)
|
|
85
|
-
setIsFocused(true)
|
|
86
|
-
|
|
87
|
-
// TODO: we should only select it when we are sure the user didn't lose focus
|
|
88
|
-
// by focusing out of the tab for instance
|
|
89
|
-
// Select the input text when focusing
|
|
90
|
-
typeaheadRef.current.getInput().select()
|
|
91
|
-
// if (e.type === "click") {
|
|
92
|
-
// return
|
|
93
|
-
// }
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const onBlur = () => {
|
|
97
|
-
console.log("onBlur: disabling menu")
|
|
98
|
-
// TODO: we should hide the menu in most blur cases
|
|
99
|
-
setIsFocused(false)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const onChange = (selection) => {
|
|
103
|
-
assert([0, 1].includes(selection.length), "unknown selection length")
|
|
104
|
-
|
|
105
|
-
console.log("selection change", selection)
|
|
106
|
-
|
|
107
|
-
if (selection.length === 0) {
|
|
108
|
-
console.log("apply selection change")
|
|
109
|
-
setSelected([])
|
|
110
|
-
return
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const onSearchCallback = useRef(
|
|
115
|
-
_throttle(
|
|
116
|
-
async(queryStr: string) => {
|
|
117
|
-
// used to not set loader before 100ms delay (if search is too fast)
|
|
118
|
-
const tm = setTimeout(() => {
|
|
119
|
-
setIsLoading(true)
|
|
120
|
-
}, 100)
|
|
121
|
-
|
|
122
|
-
const searchResults = await onSearch(queryStr)
|
|
123
|
-
|
|
124
|
-
setResults(searchResults)
|
|
125
|
-
clearTimeout(tm)
|
|
126
|
-
setIsLoading(false)
|
|
127
|
-
},
|
|
128
|
-
200,
|
|
129
|
-
{leading: true, trailing: true},
|
|
130
|
-
),
|
|
131
|
-
).current
|
|
132
|
-
|
|
133
|
-
// const onSearchAdvanced = useRef(
|
|
134
|
-
// _throttle(
|
|
135
|
-
// async(str: string) => {
|
|
136
|
-
// const search_context = selected[0]
|
|
137
|
-
// let res
|
|
138
|
-
// // TMP
|
|
139
|
-
// try {
|
|
140
|
-
// // res = await search_advanced({
|
|
141
|
-
// // group_id: envContext.groupId,
|
|
142
|
-
// // query: str,
|
|
143
|
-
// // search_context,
|
|
144
|
-
// // })
|
|
145
|
-
// console.log("TMP: search advanced is disabled", search_context, search_advanced)
|
|
146
|
-
// } catch (err) {
|
|
147
|
-
// console.log("advanced search got error", err)
|
|
148
|
-
// return
|
|
149
|
-
// }
|
|
150
|
-
// console.log("onSearchAdvanced res", res)
|
|
151
|
-
// },
|
|
152
|
-
// 1000,
|
|
153
|
-
// {leading: false},
|
|
154
|
-
// ),
|
|
155
|
-
// ).current
|
|
156
|
-
|
|
157
|
-
// perform search when input changes
|
|
158
|
-
useEffect(() => {
|
|
159
|
-
const val = currentInputValue
|
|
160
|
-
if (val.length >= minLength) {
|
|
161
|
-
onSearchCallback(val)
|
|
162
|
-
} else {
|
|
163
|
-
console.log("TODO: search input < minLength, clear results")
|
|
164
|
-
}
|
|
165
|
-
}, [currentInputValue])
|
|
166
|
-
|
|
167
|
-
const onInputChange = (v) => {
|
|
168
|
-
setCurrentInputValue(v)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const onHideResults = (e) => {
|
|
172
|
-
// console.log("hide results wow", e)
|
|
173
|
-
// when clicking on anything inside the input, we do not close menu
|
|
174
|
-
if (e instanceof MouseEvent) {
|
|
175
|
-
const {target} = e
|
|
176
|
-
if (wrapperRef.current?.contains(target)) {
|
|
177
|
-
return
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// also blur the input when closing the menu
|
|
181
|
-
// typeaheadRef.current?.clear()
|
|
182
|
-
typeaheadRef.current?.blur()
|
|
183
|
-
setShowResults(false)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// clears the input (but preserves the token "scope" if there is one)
|
|
187
|
-
const getClearHandler = (onClear) => () => {
|
|
188
|
-
typeaheadRef.current?.clear()
|
|
189
|
-
typeaheadRef.current?.focus()
|
|
190
|
-
|
|
191
|
-
// requestAnimationFrame(() => {
|
|
192
|
-
// // this.typeaheadRef.current?.focus()
|
|
193
|
-
// })
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const setSearchInput = (v) => {
|
|
197
|
-
setCurrentInputValue(v)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const onCompleteSearch = useCallback(() => {
|
|
201
|
-
typeaheadRef.current?.blur()
|
|
202
|
-
typeaheadRef.current?.clear()
|
|
203
|
-
setCurrentInputValue("")
|
|
204
|
-
setShowResults(false)
|
|
205
|
-
}, [])
|
|
206
|
-
|
|
207
|
-
const showClearButton = () => !isLoading && currentInputValue !== ""
|
|
208
|
-
|
|
209
|
-
const hasAdvancedResults = false
|
|
210
|
-
|
|
211
|
-
return (
|
|
212
|
-
<>
|
|
213
|
-
<div
|
|
214
|
-
id={id}
|
|
215
|
-
ref={wrapperRef}
|
|
216
|
-
className="d-flex mx-auto w-100"
|
|
217
|
-
// style={{height: 32, position: "relative", maxWidth: 804}}
|
|
218
|
-
style={{height: 32, position: "relative"}}
|
|
219
|
-
>
|
|
220
|
-
<Typeahead
|
|
221
|
-
id={`${id}-typeahead`}
|
|
222
|
-
ref={typeaheadRef}
|
|
223
|
-
className={cx("search-typeahead w-100", {"is-focused": isFocused})}
|
|
224
|
-
placeholder={PLACEHOLDER}
|
|
225
|
-
inputProps={{
|
|
226
|
-
placeholder: PLACEHOLDER,
|
|
227
|
-
}}
|
|
228
|
-
labelKey={"name"}
|
|
229
|
-
renderMenu={() => null}
|
|
230
|
-
onInputChange={onInputChange}
|
|
231
|
-
multiple
|
|
232
|
-
allowNew={true} // is this prop doing anything in our case?
|
|
233
|
-
onFocus={onFocus}
|
|
234
|
-
onBlur={onBlur}
|
|
235
|
-
onChange={onChange}
|
|
236
|
-
selected={selected}
|
|
237
|
-
options={selected}
|
|
238
|
-
>
|
|
239
|
-
{({onClear}) => (
|
|
240
|
-
<div className="rbt-aux">
|
|
241
|
-
{showClearButton() && (
|
|
242
|
-
<button
|
|
243
|
-
className="btn btn-link link-secondary me-2"
|
|
244
|
-
onClick={getClearHandler(onClear)}
|
|
245
|
-
style={{display: "block", zIndex: 1, pointerEvents: "auto"}}
|
|
246
|
-
>
|
|
247
|
-
clear
|
|
248
|
-
</button>
|
|
249
|
-
)}
|
|
250
|
-
{isLoading && <ActivityIndicator />}
|
|
251
|
-
{hasAdvancedResults && (
|
|
252
|
-
<div>
|
|
253
|
-
<kbd>⌘+↵</kbd>
|
|
254
|
-
</div>
|
|
255
|
-
)}
|
|
256
|
-
</div>
|
|
257
|
-
)}
|
|
258
|
-
</Typeahead>
|
|
259
|
-
</div>
|
|
260
|
-
|
|
261
|
-
<Overlay
|
|
262
|
-
target={wrapperRef.current}
|
|
263
|
-
container={wrapperRef.current}
|
|
264
|
-
placement="bottom"
|
|
265
|
-
show={showResults}
|
|
266
|
-
transition={false}
|
|
267
|
-
onHide={onHideResults}
|
|
268
|
-
rootClose={true}
|
|
269
|
-
rootCloseEvent={"mousedown"}
|
|
270
|
-
>
|
|
271
|
-
{({style, ...overlayProps}) => (
|
|
272
|
-
<div
|
|
273
|
-
id={`${id}-overlay`}
|
|
274
|
-
{...overlayProps}
|
|
275
|
-
className="shadow-lg"
|
|
276
|
-
style={{
|
|
277
|
-
...style,
|
|
278
|
-
top: 7,
|
|
279
|
-
left: -1,
|
|
280
|
-
right: -3,
|
|
281
|
-
}}
|
|
282
|
-
>
|
|
283
|
-
<SearchResults
|
|
284
|
-
id={id}
|
|
285
|
-
query={currentInputValue.trim()}
|
|
286
|
-
results={results}
|
|
287
|
-
onCompleteSearch={onCompleteSearch}
|
|
288
|
-
searchContext={selected[0]}
|
|
289
|
-
renderResultItem={renderResultItem}
|
|
290
|
-
>
|
|
291
|
-
<SearchHistory setSearchInput={setSearchInput} />
|
|
292
|
-
</SearchResults>
|
|
293
|
-
</div>
|
|
294
|
-
)}
|
|
295
|
-
</Overlay>
|
|
296
|
-
</>
|
|
297
|
-
)
|
|
298
|
-
}
|
package/ui/Search/search.scss
DELETED
|
File without changes
|
package/ui/SelectPills/index.tsx
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import "./select-pills.scss"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
direction?: "row" | "col";
|
|
6
|
-
size?: "md" | "sm";
|
|
7
|
-
items: Array<{ key: string; icon?: string; name: string; description?: string }>;
|
|
8
|
-
onChange: (key: string) => void;
|
|
9
|
-
activeKey?: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const SelectPills= ({
|
|
13
|
-
direction = "row",
|
|
14
|
-
size = "md",
|
|
15
|
-
items,
|
|
16
|
-
onChange,
|
|
17
|
-
activeKey,
|
|
18
|
-
}: Props) => {
|
|
19
|
-
const handleSelectType = (type: string) => () => {
|
|
20
|
-
onChange(type)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const renderRow = () => {
|
|
24
|
-
const iconSize = size === "sm" ? "24px" : "32px"
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div className={`select-pills mb-3 card-group direction-row`}>
|
|
28
|
-
{items.map((item, index) => (
|
|
29
|
-
<div
|
|
30
|
-
key={`pill-${index}`}
|
|
31
|
-
id={`select-pill-${item.key}`}
|
|
32
|
-
className={`card select-pill ${activeKey === item.key ? "active" : ""}`}
|
|
33
|
-
onClick={handleSelectType(item.key)}
|
|
34
|
-
>
|
|
35
|
-
<div className={`card-body d-flex p-2 ${item.description ? "flex-row" : "flex-column"}`}>
|
|
36
|
-
{item.icon && (
|
|
37
|
-
<img
|
|
38
|
-
className="d-flex mx-auto align-self-center"
|
|
39
|
-
width={iconSize}
|
|
40
|
-
height={iconSize}
|
|
41
|
-
src={item.icon}
|
|
42
|
-
/>
|
|
43
|
-
)}
|
|
44
|
-
<div className={`flex-column ${item.description ? "ms-3" : "text-center mt-2"}`}>
|
|
45
|
-
<h6 className="card-title mb-1 fw-bold">{item.name}</h6>
|
|
46
|
-
{item.description && (<p className="card-text">{item.description}</p>)}
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
))}
|
|
51
|
-
</div>
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const renderCol = () => {
|
|
56
|
-
const iconSize = size === "sm" ? "24px" : "32px"
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<div className="select-pills">
|
|
60
|
-
{items.map((item, index) => (
|
|
61
|
-
<div
|
|
62
|
-
key={`pill-${index}`}
|
|
63
|
-
id={`select-pill-${item.key}`}
|
|
64
|
-
className={`card select-pill direction-col ${activeKey === item.key ? "active" : ""}`}
|
|
65
|
-
onClick={handleSelectType(item.key)}
|
|
66
|
-
>
|
|
67
|
-
<div className="card-body d-flex flex-row px-2 py-3">
|
|
68
|
-
{item.icon && (
|
|
69
|
-
<img
|
|
70
|
-
className="d-flex align-self-center me-2"
|
|
71
|
-
style={{width: iconSize, height: iconSize}}
|
|
72
|
-
src={item.icon}
|
|
73
|
-
/>
|
|
74
|
-
)}
|
|
75
|
-
|
|
76
|
-
{size === "md" && (
|
|
77
|
-
<div className="flex-column">
|
|
78
|
-
<h6 className="card-title mb-1 fw-bold">{item.name}</h6>
|
|
79
|
-
<p className="card-text">{item.description}</p>
|
|
80
|
-
</div>
|
|
81
|
-
)}
|
|
82
|
-
{size === "sm" && (
|
|
83
|
-
<div className="">
|
|
84
|
-
<h6 className="card-title my-0 d-inline-block me-1 fw-bold">{item.name}</h6>
|
|
85
|
-
<span className="card-text">{item.description}</span>
|
|
86
|
-
</div>
|
|
87
|
-
)}
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
))}
|
|
91
|
-
</div>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return direction === "row" ? renderRow() : renderCol()
|
|
96
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
@import "helpers";
|
|
2
|
-
|
|
3
|
-
.select-pills {
|
|
4
|
-
.card.select-pill {
|
|
5
|
-
cursor: pointer;
|
|
6
|
-
user-select: none;
|
|
7
|
-
|
|
8
|
-
&:hover {
|
|
9
|
-
background: $light;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
&:active {
|
|
13
|
-
background: $gray-300;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
&.active {
|
|
17
|
-
background: $blue-300;
|
|
18
|
-
color: $white;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.select-pill {
|
|
23
|
-
.card-text {
|
|
24
|
-
color: $gray-600;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
&.active,
|
|
28
|
-
&:active {
|
|
29
|
-
.card-text {
|
|
30
|
-
color: $gray-200;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.card.select-pill.direction-col {
|
|
36
|
-
cursor: pointer;
|
|
37
|
-
user-select: none;
|
|
38
|
-
border-radius: 0;
|
|
39
|
-
border-bottom: none;
|
|
40
|
-
|
|
41
|
-
&:first-child {
|
|
42
|
-
border-top-left-radius: 3px;
|
|
43
|
-
border-top-right-radius: 3px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
&:last-child {
|
|
47
|
-
border-bottom-left-radius: 3px;
|
|
48
|
-
border-bottom-right-radius: 3px;
|
|
49
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
&:hover {
|
|
53
|
-
background: $light;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
&:active {
|
|
57
|
-
background: $gray-300;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
&.active {
|
|
61
|
-
background: $primary;
|
|
62
|
-
border-color: darken($primary, 15%);
|
|
63
|
-
color: $white;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|