dinocollab-core 1.0.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/README.md +54 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.js +431 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
- package/dist/assets/vector-404265a04f4f9c8be1f.webp +0 -0
- package/dist/node_modules/.pnpm/@rollup_plugin-typescript@1_d0d2002d9033600b6738d939bd598bc6/node_modules/tslib/tslib.es6.js +46 -0
- package/dist/node_modules/.pnpm/@rollup_plugin-typescript@1_d0d2002d9033600b6738d939bd598bc6/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/src/api-context/alert-global.js +151 -0
- package/dist/src/api-context/alert-global.js.map +1 -0
- package/dist/src/api-context/drawer-global.js +105 -0
- package/dist/src/api-context/drawer-global.js.map +1 -0
- package/dist/src/api-context/global-modal.js +87 -0
- package/dist/src/api-context/global-modal.js.map +1 -0
- package/dist/src/api-context/popover-global.js +102 -0
- package/dist/src/api-context/popover-global.js.map +1 -0
- package/dist/src/api-context/popover.js +86 -0
- package/dist/src/api-context/popover.js.map +1 -0
- package/dist/src/api-context/ui.units.js +21 -0
- package/dist/src/api-context/ui.units.js.map +1 -0
- package/dist/src/components/copy-to-clipboard.js +105 -0
- package/dist/src/components/copy-to-clipboard.js.map +1 -0
- package/dist/src/components/custom.breadcrumbs.js +61 -0
- package/dist/src/components/custom.breadcrumbs.js.map +1 -0
- package/dist/src/components/help-tooltip.js +91 -0
- package/dist/src/components/help-tooltip.js.map +1 -0
- package/dist/src/components/image-with-fallback.js +48 -0
- package/dist/src/components/image-with-fallback.js.map +1 -0
- package/dist/src/components/text-editor.js +117 -0
- package/dist/src/components/text-editor.js.map +1 -0
- package/dist/src/form/create.autocomplete.chips.js +218 -0
- package/dist/src/form/create.autocomplete.chips.js.map +1 -0
- package/dist/src/form/create.date-expired.js +201 -0
- package/dist/src/form/create.date-expired.js.map +1 -0
- package/dist/src/form/create.date-picker.js +125 -0
- package/dist/src/form/create.date-picker.js.map +1 -0
- package/dist/src/form/create.form-base.js +135 -0
- package/dist/src/form/create.form-base.js.map +1 -0
- package/dist/src/form/create.form-comfirm.js +119 -0
- package/dist/src/form/create.form-comfirm.js.map +1 -0
- package/dist/src/form/create.form-grid-layout.js +177 -0
- package/dist/src/form/create.form-grid-layout.js.map +1 -0
- package/dist/src/form/create.form-grid-layout.units.js +39 -0
- package/dist/src/form/create.form-grid-layout.units.js.map +1 -0
- package/dist/src/form/create.input-base.js +260 -0
- package/dist/src/form/create.input-base.js.map +1 -0
- package/dist/src/form/create.input.file.js +74 -0
- package/dist/src/form/create.input.file.js.map +1 -0
- package/dist/src/form/create.select-simple.js +104 -0
- package/dist/src/form/create.select-simple.js.map +1 -0
- package/dist/src/form/create.select-with-api.js +271 -0
- package/dist/src/form/create.select-with-api.js.map +1 -0
- package/dist/src/form/create.text-editor.js +156 -0
- package/dist/src/form/create.text-editor.js.map +1 -0
- package/dist/src/form/dino-form.js +42 -0
- package/dist/src/form/dino-form.js.map +1 -0
- package/dist/src/form/helper.js +157 -0
- package/dist/src/form/helper.js.map +1 -0
- package/dist/src/form/modal-wrapper.js +75 -0
- package/dist/src/form/modal-wrapper.js.map +1 -0
- package/dist/src/form/validator.js +186 -0
- package/dist/src/form/validator.js.map +1 -0
- package/dist/src/hooks/index.js +48 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/redux/create.hoc-lazy.js +67 -0
- package/dist/src/redux/create.hoc-lazy.js.map +1 -0
- package/dist/src/redux/dino.js +11 -0
- package/dist/src/redux/dino.js.map +1 -0
- package/dist/src/redux/types.js +9 -0
- package/dist/src/redux/types.js.map +1 -0
- package/dist/src/redux/ui.error-page.js +80 -0
- package/dist/src/redux/ui.error-page.js.map +1 -0
- package/dist/src/redux/vector-404.webp.js +4 -0
- package/dist/src/redux/vector-404.webp.js.map +1 -0
- package/dist/src/table/context.js +12 -0
- package/dist/src/table/context.js.map +1 -0
- package/dist/src/table/create.action-row.js +135 -0
- package/dist/src/table/create.action-row.js.map +1 -0
- package/dist/src/table/create.status-cell.js +49 -0
- package/dist/src/table/create.status-cell.js.map +1 -0
- package/dist/src/table/create.table.js +233 -0
- package/dist/src/table/create.table.js.map +1 -0
- package/dist/src/table/custom.filter-operators.js +89 -0
- package/dist/src/table/custom.filter-operators.js.map +1 -0
- package/dist/src/table/dino.js +129 -0
- package/dist/src/table/dino.js.map +1 -0
- package/dist/src/table/helpers.js +116 -0
- package/dist/src/table/helpers.js.map +1 -0
- package/dist/src/table/model-filter.js +23 -0
- package/dist/src/table/model-filter.js.map +1 -0
- package/dist/src/table/toolbar-pannel.js +134 -0
- package/dist/src/table/toolbar-pannel.js.map +1 -0
- package/dist/src/table/ui.buttons.js +60 -0
- package/dist/src/table/ui.buttons.js.map +1 -0
- package/dist/src/table/ui.units.js +201 -0
- package/dist/src/table/ui.units.js.map +1 -0
- package/dist/src/utils/dayjs-config.js +12 -0
- package/dist/src/utils/dayjs-config.js.map +1 -0
- package/dist/src/utils/helpers.js +197 -0
- package/dist/src/utils/helpers.js.map +1 -0
- package/dist/src/utils/json-object.js +38 -0
- package/dist/src/utils/json-object.js.map +1 -0
- package/dist/src/utils/query-param.js +172 -0
- package/dist/src/utils/query-param.js.map +1 -0
- package/package.json +52 -0
- package/rollup.config.js +39 -0
- package/src/@types/global.d.ts +5 -0
- package/src/api-context/alert-global.tsx +174 -0
- package/src/api-context/drawer-global.tsx +116 -0
- package/src/api-context/global-modal.tsx +109 -0
- package/src/api-context/index.ts +13 -0
- package/src/api-context/popover-global.tsx +107 -0
- package/src/api-context/popover.tsx +89 -0
- package/src/api-context/ui.units.tsx +10 -0
- package/src/components/copy-to-clipboard.tsx +86 -0
- package/src/components/custom.breadcrumbs.tsx +67 -0
- package/src/components/help-tooltip.tsx +75 -0
- package/src/components/image-with-fallback.tsx +51 -0
- package/src/components/index.tsx +1 -0
- package/src/components/input-debounce-timer.tsx +138 -0
- package/src/components/loading-buttons.tsx +35 -0
- package/src/components/text-editor.preview.tsx +30 -0
- package/src/components/text-editor.tsx +125 -0
- package/src/form/README.md +55 -0
- package/src/form/create.autocomplete.chips.tsx +199 -0
- package/src/form/create.date-expired.tsx +195 -0
- package/src/form/create.date-picker.tsx +122 -0
- package/src/form/create.form-base.tsx +102 -0
- package/src/form/create.form-comfirm.tsx +83 -0
- package/src/form/create.form-grid-layout.tsx +170 -0
- package/src/form/create.form-grid-layout.units.tsx +37 -0
- package/src/form/create.input-base.tsx +222 -0
- package/src/form/create.input.file.tsx +76 -0
- package/src/form/create.select-simple.tsx +101 -0
- package/src/form/create.select-with-api.tsx +213 -0
- package/src/form/create.text-editor.tsx +161 -0
- package/src/form/dino-form.tsx +40 -0
- package/src/form/helper.ts +132 -0
- package/src/form/index.ts +12 -0
- package/src/form/modal-wrapper.tsx +75 -0
- package/src/form/types.ts +16 -0
- package/src/form/validator.ts +202 -0
- package/src/hooks/index.ts +44 -0
- package/src/index.ts +7 -0
- package/src/lab/create.autocomplete.simple.tsx +57 -0
- package/src/lab/create.dino-store.ts +59 -0
- package/src/lab/create.multi-select-dropdown.tsx +189 -0
- package/src/lab/create.select-mul-with-api/index.tsx +271 -0
- package/src/lab/create.select-mul-with-api/table-custom.tsx +194 -0
- package/src/lab/create.select-mul-with-api/types.ts +26 -0
- package/src/lab/create.select-mul-with-api/ui.units.tsx +163 -0
- package/src/lab/filter-bar/base.tsx +162 -0
- package/src/lab/filter-bar/create.filter-bar.tsx +190 -0
- package/src/lab/filter-bar/create.filter-menu.tsx +156 -0
- package/src/lab/filter-bar/create.filter-panel.tsx +95 -0
- package/src/lab/filter-bar/create.filtered.tsx +41 -0
- package/src/lab/filter-bar/create.sort-menu.tsx +43 -0
- package/src/lab/filter-bar/demo.tsx +50 -0
- package/src/lab/filter-bar/index.ts +6 -0
- package/src/lab/filter-bar/types.ts +105 -0
- package/src/lab/filter-bar/ui.units.tsx +70 -0
- package/src/lab/grafana-dashboard/configs.ts +43 -0
- package/src/lab/grafana-dashboard/date-time-range/absolute-time-rage.tsx +137 -0
- package/src/lab/grafana-dashboard/date-time-range/helpers.ts +126 -0
- package/src/lab/grafana-dashboard/date-time-range/index.tsx +62 -0
- package/src/lab/grafana-dashboard/date-time-range/menu-wrap.tsx +101 -0
- package/src/lab/grafana-dashboard/date-time-range/quick-ranges.tsx +161 -0
- package/src/lab/grafana-dashboard/date-time-range/types.ts +9 -0
- package/src/lab/grafana-dashboard/date-time-range/units.tsx +18 -0
- package/src/lab/grafana-dashboard/helper.ts +25 -0
- package/src/lab/grafana-dashboard/hooks.tsx +79 -0
- package/src/lab/grafana-dashboard/icons.tsx +67 -0
- package/src/lab/grafana-dashboard/index.tsx +120 -0
- package/src/lab/grafana-dashboard/top-bar.tsx +62 -0
- package/src/lab/grafana-dashboard/top-bar.types.ts +5 -0
- package/src/lab/grafana-dashboard/types.ts +8 -0
- package/src/lab/media-player.core1.tsx +273 -0
- package/src/lab/media-player.muted.tsx +62 -0
- package/src/lab/media-player.units.ts +80 -0
- package/src/lab/table-grid/create.table-grid.tsx +183 -0
- package/src/lab/table-grid/demo.tsx +53 -0
- package/src/lab/table-grid/dino.tsx +8 -0
- package/src/lab/table-grid/helpers.tsx +11 -0
- package/src/lab/table-grid/index.ts +3 -0
- package/src/lab/table-grid/item-actions.tsx +138 -0
- package/src/lab/table-grid/toolbar-pannel.tsx +98 -0
- package/src/lab/table-grid/types.ts +68 -0
- package/src/redux/create.hoc-lazy.tsx +80 -0
- package/src/redux/dino.ts +9 -0
- package/src/redux/index.ts +6 -0
- package/src/redux/types.ts +27 -0
- package/src/redux/ui.error-page.tsx +62 -0
- package/src/redux/ui.units.tsx +41 -0
- package/src/redux/vector-404.webp +0 -0
- package/src/table/context.tsx +16 -0
- package/src/table/create.action-row.tsx +91 -0
- package/src/table/create.status-cell.tsx +51 -0
- package/src/table/create.table.tsx +239 -0
- package/src/table/custom.filter-operators.ts +94 -0
- package/src/table/dino.tsx +120 -0
- package/src/table/helpers.ts +94 -0
- package/src/table/index.ts +13 -0
- package/src/table/model-filter.ts +43 -0
- package/src/table/toolbar-pannel.tsx +106 -0
- package/src/table/types.ts +50 -0
- package/src/table/ui.buttons.tsx +54 -0
- package/src/table/ui.units.tsx +189 -0
- package/src/utils/dayjs-config.ts +13 -0
- package/src/utils/helpers.ts +171 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/json-object.ts +29 -0
- package/src/utils/mfe-events.tsx +34 -0
- package/src/utils/query-param.ts +129 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { Backdrop, Box, Modal, SxProps, styled } from '@mui/material'
|
|
3
|
+
|
|
4
|
+
export interface GlobalModalState {
|
|
5
|
+
sx?: SxProps
|
|
6
|
+
sxWrap?: SxProps
|
|
7
|
+
/** @default true */
|
|
8
|
+
backdropActivated?: boolean
|
|
9
|
+
onClose?: (reason?: TModalReason) => void
|
|
10
|
+
renderContent?: () => React.ReactNode
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type TModalReason = 'backdropClick' | 'escapeKeyDown'
|
|
14
|
+
|
|
15
|
+
interface GlobalModalProps {}
|
|
16
|
+
|
|
17
|
+
export type TShowModal = (value: GlobalModalState) => void
|
|
18
|
+
|
|
19
|
+
export type TCloseModal = (event?: {}, reason?: TModalReason) => void
|
|
20
|
+
|
|
21
|
+
export interface IGlobalModalContext {
|
|
22
|
+
show: TShowModal
|
|
23
|
+
close: TCloseModal
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const GlobalModalContext = React.createContext<IGlobalModalContext>({
|
|
27
|
+
close: () => {
|
|
28
|
+
console.warn('GlobalModal provider not found!')
|
|
29
|
+
},
|
|
30
|
+
show: () => {
|
|
31
|
+
console.warn('GlobalModal provider not found!')
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
export interface IMapGlobalModal {
|
|
36
|
+
context: IGlobalModalContext
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const MapGlobalModalContext = (context: (state: IGlobalModalContext) => React.ReactNode) => (
|
|
40
|
+
<GlobalModalContext.Consumer>{context}</GlobalModalContext.Consumer>
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
class GlobalModal extends Component<React.PropsWithChildren<GlobalModalProps>, GlobalModalState> implements IGlobalModalContext {
|
|
44
|
+
constructor(props: any) {
|
|
45
|
+
super(props)
|
|
46
|
+
this.state = {}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
show: TShowModal = (value) => {
|
|
50
|
+
this.setState(value)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
close: TCloseModal = (_, reason) => {
|
|
54
|
+
if (reason === 'backdropClick' && this.state.backdropActivated === false) return
|
|
55
|
+
this.setState({ renderContent: undefined })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render() {
|
|
59
|
+
return (
|
|
60
|
+
<GlobalModalContext.Provider value={this}>
|
|
61
|
+
{this.props.children}
|
|
62
|
+
<Modal
|
|
63
|
+
open={!!this.state.renderContent}
|
|
64
|
+
onClose={this.close}
|
|
65
|
+
slots={{ backdrop: Backdrop }}
|
|
66
|
+
slotProps={{ backdrop: { timeout: 300 } }}
|
|
67
|
+
sx={this.state.sx}
|
|
68
|
+
>
|
|
69
|
+
<Wrapper sx={this.state.sxWrap}>{this.renderContent()}</Wrapper>
|
|
70
|
+
</Modal>
|
|
71
|
+
</GlobalModalContext.Provider>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
renderContent = (): React.ReactNode => {
|
|
76
|
+
return this.state.renderContent ? this.state.renderContent() : <></>
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export default GlobalModal
|
|
80
|
+
|
|
81
|
+
const Wrapper = styled(Box)({
|
|
82
|
+
position: 'absolute',
|
|
83
|
+
top: '50%',
|
|
84
|
+
left: '50%',
|
|
85
|
+
transform: 'translate(-50%, -50%)',
|
|
86
|
+
outline: 'none'
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
export interface IApiGlobalModalContextProps {
|
|
90
|
+
contextGlobalModal: IGlobalModalContext
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const withApiGlobalModalContext = <P extends IApiGlobalModalContextProps>(Component: React.ComponentType<P>) => {
|
|
94
|
+
return (props: Omit<P, keyof IApiGlobalModalContextProps>) => {
|
|
95
|
+
return (
|
|
96
|
+
<GlobalModal>
|
|
97
|
+
{MapGlobalModalContext((context) => (
|
|
98
|
+
<Component {...(props as P)} contextGlobalModal={context} />
|
|
99
|
+
))}
|
|
100
|
+
</GlobalModal>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const withApiGlobalModalConsumerContext = <P extends IApiGlobalModalContextProps>(Component: React.ComponentType<P>) => {
|
|
106
|
+
return (props: Omit<P, keyof IApiGlobalModalContextProps>) => {
|
|
107
|
+
return MapGlobalModalContext((context) => <Component {...(props as P)} contextGlobalModal={context} />)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as ApiPopover } from './popover'
|
|
2
|
+
export * from './popover'
|
|
3
|
+
|
|
4
|
+
export { default as AlertGlobal } from './alert-global'
|
|
5
|
+
export * from './alert-global'
|
|
6
|
+
|
|
7
|
+
export { default as DrawerGlobal } from './drawer-global'
|
|
8
|
+
|
|
9
|
+
export { default as GlobalModal } from './global-modal'
|
|
10
|
+
export * from './global-modal'
|
|
11
|
+
|
|
12
|
+
export { default as PopoverGlobal } from './popover-global'
|
|
13
|
+
export * from './popover-global'
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React, { Component, PropsWithChildren } from 'react'
|
|
2
|
+
import { Popover, PopoverProps, PopoverVirtualElement } from '@mui/material'
|
|
3
|
+
import { ContentDefault } from './ui.units'
|
|
4
|
+
|
|
5
|
+
export interface PopoverGlobalState {
|
|
6
|
+
anchorEl?: Element | (() => Element) | PopoverVirtualElement | (() => PopoverVirtualElement) | null
|
|
7
|
+
popoverProps?: Omit<PopoverProps, 'open'>
|
|
8
|
+
content: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type OpenPopover = (value: PopoverGlobalState) => void
|
|
12
|
+
|
|
13
|
+
export type ClosePopover = (reason?: 'backdropClick' | 'escapeKeyDown') => void
|
|
14
|
+
|
|
15
|
+
export interface PopoverGlobalContext {
|
|
16
|
+
open: OpenPopover
|
|
17
|
+
close: ClosePopover
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const PopoverGlobalApi: PopoverGlobalContext = {
|
|
21
|
+
open: () => {
|
|
22
|
+
console.warn('PopoverGlobal provider not found!')
|
|
23
|
+
},
|
|
24
|
+
close: () => {
|
|
25
|
+
console.warn('PopoverGlobal provider not found!')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const PopoverGlobalContext = React.createContext<PopoverGlobalContext>(PopoverGlobalApi)
|
|
30
|
+
|
|
31
|
+
export const MapPopoverGlobalContext = (context: (state: PopoverGlobalContext) => React.ReactNode) => (
|
|
32
|
+
<PopoverGlobalContext.Consumer>{context}</PopoverGlobalContext.Consumer>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
interface IProps extends PropsWithChildren {}
|
|
36
|
+
|
|
37
|
+
export class PopoverGlobalProvider extends Component<IProps, PopoverGlobalState> {
|
|
38
|
+
constructor(props: any) {
|
|
39
|
+
super(props)
|
|
40
|
+
this.state = { anchorEl: null, content: <ContentDefault /> }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
componentDidMount() {
|
|
44
|
+
PopoverGlobalApi.open = this.openPopover
|
|
45
|
+
PopoverGlobalApi.close = this.closePopover
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
render() {
|
|
49
|
+
return (
|
|
50
|
+
<PopoverGlobalContext.Provider value={{ open: this.openPopover, close: this.closePopover }}>
|
|
51
|
+
{this.props.children}
|
|
52
|
+
<Popover
|
|
53
|
+
sx={{ '& .MuiPaper-root.MuiPaper-elevation': { overflow: 'hidden' } }}
|
|
54
|
+
anchorEl={this.state.anchorEl}
|
|
55
|
+
open={Boolean(this.state.anchorEl)}
|
|
56
|
+
onClose={(_, reason) => this.closePopover(reason)}
|
|
57
|
+
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
58
|
+
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
|
59
|
+
disableScrollLock
|
|
60
|
+
{...this.state.popoverProps}
|
|
61
|
+
>
|
|
62
|
+
{this.state.content}
|
|
63
|
+
</Popover>
|
|
64
|
+
</PopoverGlobalContext.Provider>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
openPopover: OpenPopover = (option) => {
|
|
69
|
+
clearTimeout(this.timer)
|
|
70
|
+
this.setState({ ...option })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
timer: any
|
|
74
|
+
closePopover: ClosePopover = () => {
|
|
75
|
+
clearTimeout(this.timer)
|
|
76
|
+
this.setState({ anchorEl: null }, () => {
|
|
77
|
+
this.timer = setTimeout(() => {
|
|
78
|
+
this.setState({ content: <ContentDefault /> })
|
|
79
|
+
}, 500)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface IPopoverGlobalContextProps {
|
|
85
|
+
contextPopover: PopoverGlobalContext
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const withPopoverGlobalContext = <P extends IPopoverGlobalContextProps>(Component: React.ComponentType<P>) => {
|
|
89
|
+
return (props: Omit<P, keyof IPopoverGlobalContextProps>) => {
|
|
90
|
+
return (
|
|
91
|
+
<PopoverGlobalProvider>
|
|
92
|
+
{MapPopoverGlobalContext((context) => (
|
|
93
|
+
<Component {...(props as P)} contextPopover={context} />
|
|
94
|
+
))}
|
|
95
|
+
</PopoverGlobalProvider>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const PopoverGlobal = {
|
|
101
|
+
Provider: PopoverGlobalProvider,
|
|
102
|
+
Api: PopoverGlobalApi,
|
|
103
|
+
Context: PopoverGlobalContext,
|
|
104
|
+
mapContext: MapPopoverGlobalContext
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default PopoverGlobal
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { Popover, PopoverProps, PopoverVirtualElement } from '@mui/material'
|
|
3
|
+
import { ContentDefault } from './ui.units'
|
|
4
|
+
|
|
5
|
+
export interface IPopoverOptions {
|
|
6
|
+
anchorEl?: Element | (() => Element) | PopoverVirtualElement | (() => PopoverVirtualElement) | null
|
|
7
|
+
popoverProps?: Omit<PopoverProps, 'open'>
|
|
8
|
+
content: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type TShowPopover = (option: IPopoverOptions) => void
|
|
12
|
+
|
|
13
|
+
export type TClosePopover = (reason?: 'backdropClick' | 'escapeKeyDown') => void
|
|
14
|
+
|
|
15
|
+
export interface IApiPopoverContext {
|
|
16
|
+
showPopover: TShowPopover
|
|
17
|
+
closePopover: TClosePopover
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const ApiPopoverContext = React.createContext<IApiPopoverContext>({
|
|
21
|
+
showPopover: () => {
|
|
22
|
+
console.warn('ApiPopover provider not found!')
|
|
23
|
+
},
|
|
24
|
+
closePopover: () => {
|
|
25
|
+
console.warn('ApiPopover provider not found!')
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
export const MapApiPopoverContext = (context: (state: IApiPopoverContext) => React.ReactNode) => (
|
|
30
|
+
<ApiPopoverContext.Consumer>{context}</ApiPopoverContext.Consumer>
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
interface IProps {}
|
|
34
|
+
interface IState extends IPopoverOptions {}
|
|
35
|
+
type TProps = React.PropsWithChildren<IProps>
|
|
36
|
+
class ApiPopover extends Component<TProps, IState> implements IApiPopoverContext {
|
|
37
|
+
constructor(props: any) {
|
|
38
|
+
super(props)
|
|
39
|
+
this.state = { anchorEl: null, content: <ContentDefault /> }
|
|
40
|
+
}
|
|
41
|
+
render() {
|
|
42
|
+
return (
|
|
43
|
+
<ApiPopoverContext.Provider value={this}>
|
|
44
|
+
{this.props.children}
|
|
45
|
+
<Popover
|
|
46
|
+
sx={{ '& .MuiPaper-root.MuiPaper-elevation': { overflow: 'hidden' } }}
|
|
47
|
+
anchorEl={this.state.anchorEl}
|
|
48
|
+
open={Boolean(this.state.anchorEl)}
|
|
49
|
+
onClose={(_, reason) => this.closePopover(reason)}
|
|
50
|
+
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
51
|
+
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
|
52
|
+
disableScrollLock
|
|
53
|
+
{...this.state.popoverProps}
|
|
54
|
+
>
|
|
55
|
+
{this.state.content}
|
|
56
|
+
</Popover>
|
|
57
|
+
</ApiPopoverContext.Provider>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
showPopover = (option: IPopoverOptions) => {
|
|
61
|
+
clearTimeout(this.timer)
|
|
62
|
+
this.setState({ ...option })
|
|
63
|
+
}
|
|
64
|
+
timer: any
|
|
65
|
+
closePopover: TClosePopover = () => {
|
|
66
|
+
clearTimeout(this.timer)
|
|
67
|
+
this.setState({ anchorEl: null }, () => {
|
|
68
|
+
this.timer = setTimeout(() => {
|
|
69
|
+
this.setState({ content: <ContentDefault /> })
|
|
70
|
+
}, 500)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export default ApiPopover
|
|
75
|
+
|
|
76
|
+
export interface IApiPopoverContextProps {
|
|
77
|
+
contextPopover: IApiPopoverContext
|
|
78
|
+
}
|
|
79
|
+
export const withApiPopoverContext = <P extends IApiPopoverContextProps>(Component: React.ComponentType<P>) => {
|
|
80
|
+
return (props: Omit<P, keyof IApiPopoverContextProps>) => {
|
|
81
|
+
return (
|
|
82
|
+
<ApiPopover>
|
|
83
|
+
{MapApiPopoverContext((context) => (
|
|
84
|
+
<Component {...(props as P)} contextPopover={context} />
|
|
85
|
+
))}
|
|
86
|
+
</ApiPopover>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { Box, Typography } from '@mui/material'
|
|
3
|
+
|
|
4
|
+
export const ContentDefault: FC = () => (
|
|
5
|
+
<Box sx={{ p: '9px 12px', m: '12px', backgroundColor: 'rgba(0,0,0,0.1)' }}>
|
|
6
|
+
<Typography variant='caption' sx={{ fontWeight: 600, fontStyle: 'italic' }}>
|
|
7
|
+
Content
|
|
8
|
+
</Typography>
|
|
9
|
+
</Box>
|
|
10
|
+
)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React, { Component, ComponentType } from 'react'
|
|
2
|
+
import { Box, ButtonProps, IconButton, Tooltip, TooltipProps } from '@mui/material'
|
|
3
|
+
import copy from 'clipboard-copy'
|
|
4
|
+
import DoneIcon from '@mui/icons-material/Done'
|
|
5
|
+
import ContentCopyIcon from '@mui/icons-material/ContentCopy'
|
|
6
|
+
|
|
7
|
+
interface IProps {
|
|
8
|
+
value: string
|
|
9
|
+
slots?: {
|
|
10
|
+
tooltipProps?: Partial<TooltipProps>
|
|
11
|
+
button?: ComponentType<{ onClick: () => void; copied?: boolean }>
|
|
12
|
+
buttonProps?: ButtonProps
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface IState {
|
|
17
|
+
showTooltip: boolean
|
|
18
|
+
copied: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class CopyToClipboard extends Component<IProps, IState> {
|
|
22
|
+
constructor(props: IProps) {
|
|
23
|
+
super(props)
|
|
24
|
+
this.state = { showTooltip: false, copied: false }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render() {
|
|
28
|
+
const leaveDelay = this.state.copied ? this.debounceTime.time - 200 : 0
|
|
29
|
+
const { title, ...tooltipProps } = this.props.slots?.tooltipProps ?? {}
|
|
30
|
+
const titleValue = this.state.copied ? 'Copied to clipboard!' : (title ?? 'Copy to clipboard')
|
|
31
|
+
return (
|
|
32
|
+
<Tooltip
|
|
33
|
+
arrow
|
|
34
|
+
title={titleValue}
|
|
35
|
+
leaveDelay={leaveDelay}
|
|
36
|
+
open={this.state.showTooltip}
|
|
37
|
+
onOpen={() => this.setState({ showTooltip: true })}
|
|
38
|
+
onClose={() => this.setState({ showTooltip: false })}
|
|
39
|
+
{...tooltipProps}
|
|
40
|
+
>
|
|
41
|
+
<Box sx={{ display: 'inline-block', flex: '0 0 auto' }}>{this.renderIcon()}</Box>
|
|
42
|
+
</Tooltip>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
renderIcon = () => {
|
|
47
|
+
if (this.props.slots?.button) {
|
|
48
|
+
const ButtonComp = this.props.slots.button
|
|
49
|
+
return <ButtonComp onClick={this.handleClickCopy} copied={this.state.copied} />
|
|
50
|
+
}
|
|
51
|
+
const Icon = this.state.copied ? DoneIcon : ContentCopyIcon
|
|
52
|
+
return (
|
|
53
|
+
<IconButton onClick={this.handleClickCopy} {...this.props.slots?.buttonProps}>
|
|
54
|
+
<Icon fontSize='small' sx={{ color: '#606060' }} />
|
|
55
|
+
</IconButton>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
handleClickCopy = () => {
|
|
60
|
+
this.debounceTime.start()
|
|
61
|
+
this.onCopy()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private debounceTime = {
|
|
65
|
+
cache: 0 as any,
|
|
66
|
+
time: 1500,
|
|
67
|
+
start: () => {
|
|
68
|
+
this.debounceTime.clear()
|
|
69
|
+
this.setState({ copied: true }, () => {
|
|
70
|
+
this.debounceTime.cache = setTimeout(() => {
|
|
71
|
+
this.setState({ copied: false })
|
|
72
|
+
}, this.debounceTime.time)
|
|
73
|
+
})
|
|
74
|
+
},
|
|
75
|
+
clear: () => {
|
|
76
|
+
clearTimeout(this.debounceTime.cache)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private onCopy = () => {
|
|
81
|
+
copy(this.props.value)
|
|
82
|
+
this.setState({ showTooltip: true })
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default CopyToClipboard
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { Box, Breadcrumbs, styled, Typography, TypographyProps } from '@mui/material'
|
|
3
|
+
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'
|
|
4
|
+
|
|
5
|
+
export interface CustomBreadcrumbConfig {
|
|
6
|
+
label: string
|
|
7
|
+
url?: string
|
|
8
|
+
propsGetter?: () => TypographyProps
|
|
9
|
+
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface IProps {
|
|
13
|
+
value?: CustomBreadcrumbConfig[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const CustomBreadcrumbs: FC<IProps> = (props) => {
|
|
17
|
+
const list = props.value ?? []
|
|
18
|
+
|
|
19
|
+
const handleClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, x: CustomBreadcrumbConfig) => {
|
|
20
|
+
e.preventDefault()
|
|
21
|
+
e.stopPropagation()
|
|
22
|
+
x.onClick && x.onClick(e)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const getItemProps = (item: CustomBreadcrumbConfig): TypographyProps => {
|
|
26
|
+
if (item.propsGetter) return item.propsGetter()
|
|
27
|
+
return item.url ? ({ component: 'a', href: item.url } as TypographyProps) : {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Breadcrumbs>
|
|
32
|
+
{list.map((x, i) => {
|
|
33
|
+
const isClick = !!x.onClick || !!x.url
|
|
34
|
+
return (
|
|
35
|
+
<WrapTypography
|
|
36
|
+
key={'key' + i}
|
|
37
|
+
{...getItemProps(x)}
|
|
38
|
+
onClick={x.onClick ? (e: any) => handleClick(e, x) : undefined}
|
|
39
|
+
className={isClick ? 'clickable' : ''}
|
|
40
|
+
>
|
|
41
|
+
{i < 1 && <ArrowBackIosIcon sx={{ fontSize: '16px', mb: '3px', color: '#000' }} />}
|
|
42
|
+
<Typography variant='subtitle1' sx={{ fontWeight: 600 }} noWrap>
|
|
43
|
+
<span>{x.label}</span>
|
|
44
|
+
</Typography>
|
|
45
|
+
</WrapTypography>
|
|
46
|
+
)
|
|
47
|
+
})}
|
|
48
|
+
</Breadcrumbs>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default CustomBreadcrumbs
|
|
53
|
+
|
|
54
|
+
const WrapTypography = styled(Box)({
|
|
55
|
+
display: 'flex',
|
|
56
|
+
alignItems: 'center',
|
|
57
|
+
textDecoration: 'none',
|
|
58
|
+
'&.clickable': {
|
|
59
|
+
cursor: 'pointer'
|
|
60
|
+
},
|
|
61
|
+
'& .MuiTypography-root': {
|
|
62
|
+
color: 'var(--color-title)'
|
|
63
|
+
},
|
|
64
|
+
'&.clickable:hover .MuiTypography-root': {
|
|
65
|
+
textDecoration: 'underline'
|
|
66
|
+
}
|
|
67
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React, { FC, PropsWithChildren, ReactNode } from 'react'
|
|
2
|
+
import { Box, Divider, IconButton, Stack, Tooltip, Typography } from '@mui/material'
|
|
3
|
+
import { SxProps, Theme, TooltipProps, TypographyProps, styled, tooltipClasses } from '@mui/material'
|
|
4
|
+
import HelpOutlineIcon from '@mui/icons-material/HelpOutline'
|
|
5
|
+
|
|
6
|
+
interface IProps {
|
|
7
|
+
title: string
|
|
8
|
+
small?: boolean
|
|
9
|
+
sxIcon?: SxProps<Theme>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const HelpTooltip: FC<PropsWithChildren<IProps>> = (props) => (
|
|
13
|
+
<HtmlTooltip
|
|
14
|
+
arrow
|
|
15
|
+
placement='bottom'
|
|
16
|
+
title={
|
|
17
|
+
<Stack sx={{ gap: '6px', py: '6px', minWidth: '200px', maxWidth: '400px ' }}>
|
|
18
|
+
<TooltipHeaderText>{props.title}</TooltipHeaderText>
|
|
19
|
+
<Divider />
|
|
20
|
+
<Box sx={{ p: '6px 12px' }}>{props.children}</Box>
|
|
21
|
+
</Stack>
|
|
22
|
+
}
|
|
23
|
+
>
|
|
24
|
+
<Box sx={{ cursor: 'default', ...props.sxIcon }}>
|
|
25
|
+
<IconButton size='small'>
|
|
26
|
+
<HelpOutlineIcon fontSize={props.small ? 'small' : 'medium'} sx={{ color: 'rgb(25,103,210)' }} />
|
|
27
|
+
</IconButton>
|
|
28
|
+
</Box>
|
|
29
|
+
</HtmlTooltip>
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export default HelpTooltip
|
|
33
|
+
|
|
34
|
+
interface IHelpTooltipWrapProps {
|
|
35
|
+
content: ReactNode
|
|
36
|
+
title: string
|
|
37
|
+
children: React.ReactNode
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const HelpTooltipWrap: FC<IHelpTooltipWrapProps> = (props) => (
|
|
41
|
+
<HtmlTooltip
|
|
42
|
+
arrow
|
|
43
|
+
placement='bottom'
|
|
44
|
+
title={
|
|
45
|
+
<Stack sx={{ gap: '6px', py: '6px', minWidth: '200px', maxWidth: '400px ' }}>
|
|
46
|
+
<TooltipHeaderText>{props.title}</TooltipHeaderText>
|
|
47
|
+
<Divider />
|
|
48
|
+
<Box sx={{ p: '6px 12px' }}>{props.content}</Box>
|
|
49
|
+
</Stack>
|
|
50
|
+
}
|
|
51
|
+
>
|
|
52
|
+
<Box sx={{ cursor: 'default' }}>{props.children}</Box>
|
|
53
|
+
</HtmlTooltip>
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const TooltipHeaderText = styled((props: TypographyProps) => <Typography variant='subtitle1' {...props} />)({
|
|
57
|
+
color: '#0095ff',
|
|
58
|
+
fontWeight: 700,
|
|
59
|
+
padding: '0 10px'
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const HtmlTooltip = styled(({ className, ...props }: TooltipProps) => <Tooltip {...props} classes={{ popper: className }} />)(({ theme }) => ({
|
|
63
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
64
|
+
backgroundColor: '#fff',
|
|
65
|
+
color: '#3c3c3c',
|
|
66
|
+
maxWidth: 500,
|
|
67
|
+
minHeight: 120,
|
|
68
|
+
fontSize: theme.typography.pxToRem(12),
|
|
69
|
+
borderRadius: '8px',
|
|
70
|
+
boxShadow: 'rgba(0, 0, 0, 0.08) 0px 6px 30px'
|
|
71
|
+
},
|
|
72
|
+
[`& .${tooltipClasses.arrow}`]: {
|
|
73
|
+
color: '#fff'
|
|
74
|
+
}
|
|
75
|
+
}))
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { Fragment, ReactNode, useEffect, useState } from 'react'
|
|
2
|
+
import { useDebounce } from '../hooks'
|
|
3
|
+
|
|
4
|
+
export interface ImageWithFallbackPropsOwner {
|
|
5
|
+
src?: string
|
|
6
|
+
alt?: string
|
|
7
|
+
fallbackSrc: string
|
|
8
|
+
loading?: ReactNode
|
|
9
|
+
debounceDelay?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type ImgProps = Omit<React.ImgHTMLAttributes<HTMLImageElement>, keyof ImageWithFallbackPropsOwner>
|
|
13
|
+
|
|
14
|
+
export interface ImageWithFallbackProps extends ImgProps, ImageWithFallbackPropsOwner {}
|
|
15
|
+
|
|
16
|
+
const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({ src, fallbackSrc, alt, loading, debounceDelay = 0, ...props }) => {
|
|
17
|
+
const debouncedSrc = useDebounce(src, debounceDelay)
|
|
18
|
+
const debouncedFallbackSrc = useDebounce(fallbackSrc, debounceDelay)
|
|
19
|
+
|
|
20
|
+
const effectiveSrc = debounceDelay > 0 ? debouncedSrc : src
|
|
21
|
+
const effectiveFallbackSrc = debounceDelay > 0 ? debouncedFallbackSrc : fallbackSrc
|
|
22
|
+
|
|
23
|
+
const [isLoading, setLoading] = useState(true)
|
|
24
|
+
const [imgSrc, setImgSrc] = useState(effectiveSrc ?? effectiveFallbackSrc)
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
setImgSrc(effectiveSrc ?? effectiveFallbackSrc)
|
|
28
|
+
setLoading(true)
|
|
29
|
+
}, [effectiveSrc, effectiveFallbackSrc])
|
|
30
|
+
|
|
31
|
+
const loadingElement = isLoading && loading ? loading : <></>
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Fragment>
|
|
35
|
+
{loadingElement}
|
|
36
|
+
<img
|
|
37
|
+
{...props}
|
|
38
|
+
src={imgSrc}
|
|
39
|
+
alt={alt}
|
|
40
|
+
onLoadStart={() => setLoading(true)}
|
|
41
|
+
onLoad={() => setLoading(false)}
|
|
42
|
+
onError={() => {
|
|
43
|
+
setImgSrc(fallbackSrc)
|
|
44
|
+
setLoading(false)
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
</Fragment>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default ImageWithFallback
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|