dinocollab-core 2.0.1 → 2.0.3
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/dist/data-view/ui.units.js.map +1 -1
- package/dist/http-service/index.js +1 -1
- package/dist/mfe-shared/auth.js +2 -0
- package/dist/mfe-shared/auth.js.map +1 -0
- package/dist/mfe-shared/auth.ssr.js +2 -0
- package/dist/mfe-shared/auth.ssr.js.map +1 -0
- package/dist/mfe-shared/auth.types.js +2 -0
- package/dist/mfe-shared/auth.types.js.map +1 -0
- package/dist/mfe-shared/cart.js +2 -0
- package/dist/mfe-shared/cart.js.map +1 -0
- package/dist/mfe-shared/cart.ssr.js +2 -0
- package/dist/mfe-shared/cart.ssr.js.map +1 -0
- package/dist/mfe-shared/environment.js +2 -0
- package/dist/mfe-shared/environment.js.map +1 -0
- package/dist/mfe-shared/hydration-helper.js +2 -0
- package/dist/mfe-shared/hydration-helper.js.map +1 -0
- package/dist/mfe-shared/index.js +2 -0
- package/dist/mfe-shared/mfe-bridge.js +2 -0
- package/dist/mfe-shared/mfe-bridge.js.map +1 -0
- package/dist/mfe-shared/navigation.js +2 -0
- package/dist/mfe-shared/navigation.js.map +1 -0
- package/dist/types/http-service/base/index.d.ts +0 -1
- package/dist/types/mfe-navigate/mfe-navigate.debug.d.ts +4 -0
- package/dist/types/{mfe-modules → mfe-navigate}/mfe-navigate.remote.d.ts +4 -3
- package/dist/types/{mfe-modules → mfe-navigate}/react/provider.d.ts +1 -1
- package/dist/types/mfe-navigate/types.d.ts +13 -0
- package/dist/types/mfe-shared/auth.d.ts +45 -0
- package/dist/types/mfe-shared/auth.ssr.d.ts +53 -0
- package/dist/types/mfe-shared/auth.types.d.ts +53 -0
- package/dist/types/mfe-shared/cart.d.ts +59 -0
- package/dist/types/mfe-shared/cart.debug.d.ts +8 -0
- package/dist/types/mfe-shared/cart.ssr.d.ts +39 -0
- package/dist/types/mfe-shared/environment.d.ts +18 -0
- package/dist/types/mfe-shared/hydration-helper.d.ts +46 -0
- package/dist/types/mfe-shared/index.d.ts +21 -0
- package/dist/types/mfe-shared/mfe-bridge.d.ts +46 -0
- package/dist/types/mfe-shared/navigation.d.ts +31 -0
- package/dist/types/mfe-shared/navigation.debug.d.ts +4 -0
- package/dist/types/mfe-shared/types.d.ts +11 -0
- package/package.json +6 -27
- package/dist/http-service/base/types.js +0 -2
- package/dist/http-service/base/types.js.map +0 -1
- package/dist/mfe-modules/index.js +0 -2
- package/dist/mfe-modules/mfe-navigate.debug.js +0 -2
- package/dist/mfe-modules/mfe-navigate.debug.js.map +0 -1
- package/dist/mfe-modules/mfe-navigate.remote.js +0 -2
- package/dist/mfe-modules/mfe-navigate.remote.js.map +0 -1
- package/dist/mfe-modules/nextjs/index.js +0 -2
- package/dist/mfe-modules/nextjs/index.js.map +0 -1
- package/dist/mfe-modules/nextjs/provider.js +0 -2
- package/dist/mfe-modules/nextjs/provider.js.map +0 -1
- package/dist/mfe-modules/react/index.js +0 -2
- package/dist/mfe-modules/react/index.js.map +0 -1
- package/dist/mfe-modules/react/provider.js +0 -2
- package/dist/mfe-modules/react/provider.js.map +0 -1
- package/dist/types/mfe-modules/mfe-navigate.debug.d.ts +0 -2
- package/dist/types/mfe-modules/types.d.ts +0 -7
- /package/dist/{mfe-modules → mfe-shared}/index.js.map +0 -0
- /package/dist/types/{mfe-modules → mfe-navigate}/index.d.ts +0 -0
- /package/dist/types/{mfe-modules → mfe-navigate}/nextjs/index.d.ts +0 -0
- /package/dist/types/{mfe-modules → mfe-navigate}/nextjs/provider.d.ts +0 -0
- /package/dist/types/{mfe-modules → mfe-navigate}/react/index.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.units.js","sources":["../../src/data-view/ui.units.tsx"],"sourcesContent":["import React, { FC, ReactNode, useState } from 'react'\r\nimport { Box, Button, ButtonProps, Fade, IconButton, InputBaseProps, Typography } from '@mui/material'\r\nimport { FormControlLabel, FormGroup, Radio, RadioGroup, TextField, colors, styled } from '@mui/material'\r\nimport { ToggleButton, Tooltip, ToggleButtonGroup, Checkbox, IconButtonProps, InputAdornment, InputBase } from '@mui/material'\r\nimport CloseIcon from '@mui/icons-material/Close'\r\nimport ShuffleIcon from '@mui/icons-material/Shuffle'\r\nimport ClearAllIcon from '@mui/icons-material/ClearAll'\r\nimport FilterListIcon from '@mui/icons-material/FilterList'\r\nimport ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'\r\nimport ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'\r\nimport KeyboardReturnIcon from '@mui/icons-material/KeyboardReturn'\r\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\r\nimport { mapDataViewContext } from './context'\r\nimport { IFilterLogic, IFilterDateLogic, IFilterDateRangeLogic, IFilterSelectDef, IValidationResult, IFilterDateDef, IFilterBasicDef } from './types'\r\nimport HelpTooltip from '../components/help-tooltip'\r\n\r\nexport const mapSortConfigs: Record<'asc' | 'desc', { title: string; icon: ReactNode }> = {\r\n asc: { title: 'Ascending', icon: <ArrowUpwardIcon fontSize='small' /> },\r\n desc: { title: 'Descending', icon: <ArrowDownwardIcon fontSize='small' /> }\r\n}\r\n\r\n//#region Toggle Components\r\nexport interface IFilterLogicToggleProps {\r\n value?: IFilterLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterLogic) => void\r\n}\r\n\r\nexport const FilterLogicToggle: FC<IFilterLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'and'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='and' aria-label='and logic'>\r\n AND\r\n </ToggleButton>\r\n <ToggleButton size='small' value='or' aria-label='or logic'>\r\n OR\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nexport interface IDateLogicToggleProps {\r\n value?: IFilterDateLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterDateLogic) => void\r\n}\r\n\r\nexport const DateLogicToggle: FC<IDateLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterDateLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'before'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='before' aria-label='before date'>\r\n before\r\n </ToggleButton>\r\n <ToggleButton size='small' value='after' aria-label='after date'>\r\n after\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nexport interface IDateRangeLogicToggleProps {\r\n value?: IFilterDateRangeLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterDateRangeLogic) => void\r\n}\r\n\r\nexport const DateRangeLogicToggle: FC<IDateRangeLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterDateRangeLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'between'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='between' aria-label='between dates'>\r\n between\r\n </ToggleButton>\r\n <ToggleButton size='small' value='not-between' aria-label='not between dates'>\r\n not between\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nconst ToggleButtonGroupCustom = styled(ToggleButtonGroup)({\r\n '& .MuiToggleButton-root': {\r\n color: '#fff',\r\n borderColor: 'rgba(255, 255, 255, 0.3)',\r\n fontSize: '0.65rem',\r\n fontWeight: 600,\r\n lineHeight: 1,\r\n minWidth: '40px',\r\n padding: '6px 8px',\r\n '&.Mui-selected': {\r\n backgroundColor: '#1976d2',\r\n color: '#fff',\r\n '&:hover': {\r\n backgroundColor: '#1565c0'\r\n }\r\n },\r\n '&:hover': {\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)'\r\n }\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Notes\r\nexport interface IFilterNotesProps {\r\n title?: string\r\n items?: string[]\r\n disabledSize?: boolean\r\n renderContent?: () => ReactNode\r\n}\r\n\r\nconst HelpTooltipContent: FC<{ items: string[] }> = (props) => (\r\n <WrapList>\r\n {props.items.map((item, index) => (\r\n <Typography key={index} component='li' variant='body2'>\r\n {item}\r\n </Typography>\r\n ))}\r\n </WrapList>\r\n)\r\n\r\nexport const FilterNotes: FC<IFilterNotesProps> = (props) => (\r\n <WrapIcon className={props.disabledSize === true ? 'disabled-size' : ''}>\r\n <HelpTooltip small title={props.title ?? 'The search includes'}>\r\n {props.renderContent ? props.renderContent() : <HelpTooltipContent items={props.items ?? []} />}\r\n </HelpTooltip>\r\n </WrapIcon>\r\n)\r\n//#endregion\r\n\r\n//#region Input\r\nexport const FilterInput = React.forwardRef<HTMLInputElement, InputBaseProps>((props, ref) => {\r\n return <InputBase fullWidth autoComplete='off' size='small' {...props} inputRef={ref} />\r\n})\r\n\r\ninterface IFilterInputAdornmentProps {\r\n notes?: IFilterNotesProps\r\n keyword?: string\r\n onClear: IconButtonProps['onClick']\r\n onEnterSearch: ButtonProps['onClick']\r\n}\r\n\r\nexport const FilterInputAdornment: FC<IFilterInputAdornmentProps> = (props) => (\r\n <InputAdornment position='end'>\r\n {props.keyword && (\r\n <>\r\n <HelpButton size='small' color='primary' onClick={props.onEnterSearch} sx={{ display: { xs: 'none', md: 'flex' } }}>\r\n <Typography variant='caption'>\r\n Type and hit <b>Enter ⏎</b> to filter.\r\n </Typography>\r\n </HelpButton>\r\n <Tooltip title='Press Enter to filter' placement='bottom' arrow>\r\n <IconButton size='small' color='primary' sx={{ display: { xs: 'flex', md: 'none' } }} onClick={props.onEnterSearch}>\r\n <KeyboardReturnIcon fontSize='small' />\r\n </IconButton>\r\n </Tooltip>\r\n </>\r\n )}\r\n {props.keyword && (\r\n <Tooltip title='Press Esc to clear' placement='bottom' arrow>\r\n <IconButton\r\n size='small'\r\n sx={{\r\n marginLeft: '8px',\r\n color: 'text.error',\r\n '&:hover': { color: 'error.main' }\r\n }}\r\n onClick={props.onClear}\r\n >\r\n <CloseIcon fontSize='small' />\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {props.notes && <FilterNotes {...props.notes} />}\r\n </InputAdornment>\r\n)\r\n\r\nconst HelpButton = styled(Button)({\r\n padding: '4px 6px',\r\n textTransform: 'none',\r\n lineHeight: 1,\r\n '.MuiTypography-root': {\r\n fontWeight: 600,\r\n b: {\r\n fontWeight: 700,\r\n backgroundColor: colors.blue[100],\r\n borderRadius: '4px',\r\n padding: '2px 4px'\r\n }\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Button\r\nexport interface IButtonClearProps {\r\n visibled?: boolean\r\n onClick: IconButtonProps['onClick']\r\n}\r\n\r\nexport const ButtonClear: FC<IButtonClearProps> = (props) => (\r\n <WrapIcon>\r\n <Tooltip title='Remove filter'>\r\n <Fade in={props.visibled} unmountOnExit>\r\n <IconButton size='small' onClick={props.onClick}>\r\n <CloseIcon fontSize='small' />\r\n </IconButton>\r\n </Fade>\r\n </Tooltip>\r\n </WrapIcon>\r\n)\r\n\r\nexport const ClearAllButton = React.forwardRef<HTMLButtonElement, ButtonProps>(({ children, ...props }, ref) => (\r\n <ClearButtonStyled size='small' color='error' startIcon={<ClearAllIcon />} ref={ref} {...props}>\r\n {children || 'Clear all'}\r\n </ClearButtonStyled>\r\n))\r\n\r\nconst ClearButtonStyled = styled(Button)({ textTransform: 'none', fontWeight: 700 })\r\n\r\nexport const FilterButton = React.forwardRef<HTMLButtonElement, IconButtonProps>((props, ref) => (\r\n <IconButton ref={ref} size='small' sx={{ flex: '0 0 auto' }} {...props}>\r\n <FilterListIcon />\r\n </IconButton>\r\n))\r\n\r\nexport const SortIconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>((props, ref) => (\r\n <IconButton ref={ref} size='small' sx={{ flex: '0 0 auto' }} {...props}>\r\n <ShuffleIcon />\r\n </IconButton>\r\n))\r\n\r\nexport const SortButton: FC<ButtonProps> = (props) => (\r\n <>\r\n {mapDataViewContext((context) => {\r\n const { filterState, filterBarConfigs: configs } = context\r\n const config: Partial<{ title: string; icon: ReactNode }> = filterState.sort ? mapSortConfigs[filterState.sort?.direction] : {}\r\n const fieldConfig = configs.fields?.[filterState.sort?.field as any]\r\n const text = fieldConfig?.label || filterState.sort?.field.toString() || configs.sortButton?.text\r\n return (\r\n <SortButtonStyled\r\n size='small'\r\n color='inherit'\r\n startIcon={config.icon || <ShuffleIcon fontSize='small' />}\r\n endIcon={configs.sortButton?.icon ?? <KeyboardArrowDownIcon fontSize='small' />}\r\n onClick={(e) => context.onPopperPanelChange(e.currentTarget, 'sortButton')}\r\n {...configs.sortButton?.wrapProps}\r\n {...props}\r\n >\r\n {text || 'Sort'}\r\n </SortButtonStyled>\r\n )\r\n })}\r\n </>\r\n)\r\n\r\nconst SortButtonStyled = styled(Button)({\r\n height: 'var(--filter-bar-height, 40px)',\r\n padding: '0 16px',\r\n backgroundColor: colors.grey[50],\r\n border: '1px solid var(--color-divider, rgba(145 158 171 / 20%))',\r\n textTransform: 'none',\r\n fontWeight: 600,\r\n ':hover': {\r\n backgroundColor: colors.grey[100]\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Panel Not Found\r\nexport const PanelNotFound: FC<{ area?: string }> = ({ area }) => (\r\n <Box sx={{ padding: '8px', textAlign: 'center', border: '1px solid #ddd', borderRadius: '4px' }}>\r\n <Typography variant='body2' sx={{ padding: '8px' }}>\r\n No panel available for area: {area}\r\n </Typography>\r\n </Box>\r\n)\r\n//#endregion\r\n\r\n//#region Form\r\ninterface IFormContentProps {\r\n label: string\r\n notes?: any\r\n children?: React.ReactNode\r\n afterTopBar?: React.ReactNode\r\n}\r\n\r\nconst FormContent: FC<IFormContentProps> = ({ label, notes, children, afterTopBar }) => (\r\n <FormContentWrapper>\r\n <Box className='top-bar'>\r\n <Typography variant='subtitle2'>{label}</Typography>\r\n {afterTopBar && <Box className='after-top-bar'>{afterTopBar}</Box>}\r\n {notes && <FilterNotes title={`The ${label} includes`} disabledSize {...notes} />}\r\n </Box>\r\n <Box className='content'>{children}</Box>\r\n </FormContentWrapper>\r\n)\r\n\r\nconst FormContentWrapper = styled(Box)({\r\n minWidth: '200px',\r\n borderRadius: '4px',\r\n overflow: 'hidden',\r\n '.top-bar': {\r\n display: 'flex',\r\n alignItems: 'center',\r\n background: colors.grey[900],\r\n padding: '8px',\r\n gap: '8px',\r\n '.MuiTypography-root': {\r\n color: colors.common.white,\r\n flex: 1\r\n }\r\n },\r\n '.after-top-bar': {\r\n marginLeft: '8px'\r\n },\r\n '.content': {\r\n padding: '8px'\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Menu - String Type\r\ninterface IMenuWithTypeBaseProps {\r\n name: string\r\n validationResult?: IValidationResult\r\n}\r\n\r\ninterface IMenuWithTypeStringProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterBasicDef\r\n}\r\n\r\nexport const MenuWithTypeString: FC<IMenuWithTypeStringProps> = (props) => {\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent label={label} notes={props.fieldConfig?.notes}>\r\n <TextField\r\n autoFocus\r\n name={props.name}\r\n size='small'\r\n fullWidth\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n />\r\n </FormContent>\r\n )\r\n}\r\n//#endregion\r\n\r\n//#region Menu - Select Type\r\nexport interface IMenuWithTypeSelectProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterSelectDef\r\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void\r\n}\r\n\r\nexport const MenuWithTypeSelect: FC<IMenuWithTypeSelectProps> = (props) => {\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent label={label} notes={props.fieldConfig?.notes}>\r\n <CustomRadioGroup name={props.name} className={props.validationResult?.hasError ? 'error' : ''} onChange={props.onChange}>\r\n {props.fieldConfig?.options.map((x, i) => (\r\n <FormControlLabel key={x.value.toString() + i} value={x.value} control={<Radio />} label={x.label ?? x.value} />\r\n ))}\r\n </CustomRadioGroup>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst CustomRadioGroup = styled(RadioGroup)({\r\n marginLeft: '-8px',\r\n marginRight: '-8px',\r\n '&.error .MuiRadio-root': {\r\n color: '#d32f2f'\r\n },\r\n '.MuiFormControlLabel-root': {\r\n margin: 0\r\n },\r\n '.MuiFormControlLabel-root:hover': {\r\n backgroundColor: 'rgba(25, 118, 210, 0.04)'\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Menu - Select Multi Type\r\nexport interface IMenuWithTypeSelectMultiProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterSelectDef\r\n onChange?: (event: React.SyntheticEvent, checked: boolean) => void\r\n}\r\n\r\nexport const MenuWithTypeSelectMulti: FC<IMenuWithTypeSelectMultiProps> = (props) => {\r\n const [filterLogic, setFilterLogic] = useState<IFilterLogic>('and')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<FilterLogicToggle value={filterLogic} onChange={(_, value) => setFilterLogic(value)} />}\r\n >\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='filterLogic' value={filterLogic} />\r\n <CustomFormGroup className={props.validationResult?.hasError ? 'error' : ''}>\r\n {props.fieldConfig?.options.map((x, i) => (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n control={<Checkbox name={props.name} />}\r\n label={x.label ?? x.value}\r\n onChange={props.onChange}\r\n />\r\n ))}\r\n </CustomFormGroup>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst CustomFormGroup = styled(FormGroup)({\r\n marginLeft: '-8px',\r\n marginRight: '-8px',\r\n '&.error .MuiCheckbox-root': {\r\n color: '#d32f2f'\r\n },\r\n '.MuiFormControlLabel-root': {\r\n margin: 0\r\n },\r\n '.MuiFormControlLabel-root:hover': {\r\n backgroundColor: 'rgba(25, 118, 210, 0.04)'\r\n }\r\n})\r\n//#endregion\r\n\r\nfunction convertDateToCustomFormat(dateString: string): string {\r\n if (!dateString || !/^\\d{4}-\\d{2}-\\d{2}$/.test(dateString)) return ''\r\n return `${dateString}T00:00:00.0000000`\r\n}\r\n//#region Menu - Date Type\r\nexport interface IMenuWithTypeDateProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterDateDef\r\n}\r\n\r\nexport const MenuWithTypeDate: FC<IMenuWithTypeDateProps> = (props) => {\r\n const [dateLogic, setDateLogic] = useState<IFilterDateLogic>('before')\r\n const [value, setValue] = useState<string>('')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<DateLogicToggle value={dateLogic} onChange={(_, value) => setDateLogic(value)} />}\r\n >\r\n <Box className='content'>\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='dateLogic' value={dateLogic} />\r\n <input hidden type='text' name={props.name} readOnly value={convertDateToCustomFormat(value)} />\r\n <TextField\r\n autoFocus\r\n fullWidth\r\n type='date'\r\n size='small'\r\n value={value}\r\n onChange={(event) => setValue(event.target.value)}\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n </Box>\r\n </FormContent>\r\n )\r\n}\r\n//#endregion\r\n\r\n//#region Menu - Date Range Type\r\nexport interface IMenuWithTypeDateRangeProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterDateDef\r\n}\r\n\r\nexport const MenuWithTypeDateRange: FC<IMenuWithTypeDateRangeProps> = (props) => {\r\n const [dateRangeLogic, setDateRangeLogic] = useState<IFilterDateRangeLogic>('between')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<DateRangeLogicToggle value={dateRangeLogic} onChange={(_, value) => setDateRangeLogic(value)} />}\r\n >\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='dateRangeLogic' value={dateRangeLogic} />\r\n <DateRangeContainer>\r\n <TextField\r\n autoFocus\r\n fullWidth\r\n name={`${props.name}_start`}\r\n type='date'\r\n size='small'\r\n label='From'\r\n error={!!props.validationResult?.hasError}\r\n sx={{ marginBottom: 1 }}\r\n InputLabelProps={{ shrink: true }}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n <TextField\r\n fullWidth\r\n name={`${props.name}_end`}\r\n type='date'\r\n size='small'\r\n label='To'\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n InputLabelProps={{ shrink: true }}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n </DateRangeContainer>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst DateRangeContainer = styled(Box)({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px'\r\n})\r\n//#endregion\r\n\r\n//#region Styled\r\nconst WrapIcon = styled(Box)({\r\n display: 'inline-flex',\r\n flex: '0 0 auto',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n '&:not(.disabled-size)': {\r\n width: '40px',\r\n height: '40px'\r\n }\r\n})\r\n\r\nconst WrapList = styled('ul')({\r\n paddingLeft: '1.7rem',\r\n marginBottom: 0,\r\n li: {\r\n position: 'relative',\r\n textAlign: 'justify',\r\n '&::before': {\r\n content: '\"►\"',\r\n display: 'block',\r\n position: 'absolute',\r\n top: '50%',\r\n right: 'calc(100% + 6px)',\r\n transform: 'translateY(-50%)',\r\n fontSize: '0.9em'\r\n }\r\n }\r\n})\r\n//#endregion\r\n"],"names":["mapSortConfigs","asc","title","icon","_jsx","ArrowUpwardIcon","fontSize","desc","ArrowDownwardIcon","FilterLogicToggle","props","_jsxs","ToggleButtonGroupCustom","size","value","exclusive","onChange","event","newValue","children","ToggleButton","DateLogicToggle","DateRangeLogicToggle","styled","ToggleButtonGroup","color","borderColor","fontWeight","lineHeight","minWidth","padding","backgroundColor","HelpTooltipContent","WrapList","items","map","item","index","Typography","component","variant","FilterNotes","_props$title","_props$items","WrapIcon","className","disabledSize","HelpTooltip","small","renderContent","FilterInput","React","forwardRef","ref","InputBase","_objectSpread","fullWidth","autoComplete","inputRef","FilterInputAdornment","InputAdornment","position","keyword","_Fragment","HelpButton","onClick","onEnterSearch","sx","display","xs","md","Tooltip","placement","arrow","IconButton","KeyboardReturnIcon","marginLeft","onClear","CloseIcon","notes","Button","textTransform","b","colors","blue","borderRadius","ClearAllButton","_ref","_objectWithoutProperties","_excluded","ClearButtonStyled","startIcon","ClearAllIcon","FilterButton","flex","FilterListIcon","SortButton","mapDataViewContext","context","_filterState$sort","_configs$fields","_filterState$sort2","_filterState$sort3","_configs$sortButton","_configs$sortButton$i","_configs$sortButton2","_configs$sortButton3","filterState","configs","filterBarConfigs","config","sort","direction","fieldConfig","fields","field","text","label","toString","sortButton","SortButtonStyled","ShuffleIcon","endIcon","KeyboardArrowDownIcon","e","onPopperPanelChange","currentTarget","wrapProps","height","grey","border","PanelNotFound","_ref2","area","Box","textAlign","FormContent","_ref3","afterTopBar","FormContentWrapper","concat","overflow","alignItems","background","gap","common","white","MenuWithTypeString","_props$fieldConfig$la","_props$fieldConfig","_props$fieldConfig2","_props$validationResu","_props$validationResu2","name","TextField","autoFocus","error","validationResult","hasError","helperText","message","MenuWithTypeSelect","_props$fieldConfig$la2","_props$fieldConfig3","_props$fieldConfig4","_props$validationResu3","_props$fieldConfig5","CustomRadioGroup","options","x","i","_x$label","FormControlLabel","control","Radio","RadioGroup","marginRight","margin","MenuWithTypeSelectMulti","_props$fieldConfig$la3","_props$fieldConfig6","_props$fieldConfig7","_props$validationResu4","_props$fieldConfig8","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","_","type","CustomFormGroup","_x$label2","Checkbox","FormGroup","MenuWithTypeDate","_props$fieldConfig$la4","_props$fieldConfig9","_props$fieldConfig0","_props$validationResu5","_props$validationResu6","_props$fieldConfig1","_props$fieldConfig10","dateString","_useState3","_useState4","dateLogic","setDateLogic","_useState5","_useState6","setValue","hidden","readOnly","test","target","inputProps","min","minDate","max","maxDate","MenuWithTypeDateRange","_props$fieldConfig$la5","_props$fieldConfig11","_props$fieldConfig12","_props$validationResu7","_props$fieldConfig13","_props$fieldConfig14","_props$validationResu8","_props$validationResu9","_props$fieldConfig15","_props$fieldConfig16","_useState7","_useState8","dateRangeLogic","setDateRangeLogic","DateRangeContainer","marginBottom","InputLabelProps","shrink","flexDirection","justifyContent","width","paddingLeft","li","content","top","right","transform"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ui.units.js","sources":["../../src/data-view/ui.units.tsx"],"sourcesContent":["import React, { FC, ReactNode, useState } from 'react'\r\nimport { Box, Button, ButtonProps, Fade, IconButton, InputBaseProps, Typography } from '@mui/material'\r\nimport { FormControlLabel, FormGroup, Radio, RadioGroup, TextField, colors, styled } from '@mui/material'\r\nimport { ToggleButton, Tooltip, ToggleButtonGroup, Checkbox, IconButtonProps, InputAdornment, InputBase } from '@mui/material'\r\nimport CloseIcon from '@mui/icons-material/Close'\r\nimport ShuffleIcon from '@mui/icons-material/Shuffle'\r\nimport ClearAllIcon from '@mui/icons-material/ClearAll'\r\nimport FilterListIcon from '@mui/icons-material/FilterList'\r\nimport ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'\r\nimport ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'\r\nimport KeyboardReturnIcon from '@mui/icons-material/KeyboardReturn'\r\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'\r\nimport { mapDataViewContext } from './context'\r\nimport { IFilterLogic, IFilterDateLogic, IFilterDateRangeLogic, IFilterSelectDef, IValidationResult, IFilterDateDef, IFilterBasicDef } from './types'\r\nimport HelpTooltip from '../components/help-tooltip'\r\n\r\nexport const mapSortConfigs: Record<'asc' | 'desc', { title: string; icon: ReactNode }> = {\r\n asc: { title: 'Ascending', icon: <ArrowUpwardIcon fontSize='small' /> },\r\n desc: { title: 'Descending', icon: <ArrowDownwardIcon fontSize='small' /> }\r\n}\r\n\r\n//#region Toggle Components\r\nexport interface IFilterLogicToggleProps {\r\n value?: IFilterLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterLogic) => void\r\n}\r\n\r\nexport const FilterLogicToggle: FC<IFilterLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'and'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='and' aria-label='and logic'>\r\n AND\r\n </ToggleButton>\r\n <ToggleButton size='small' value='or' aria-label='or logic'>\r\n OR\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nexport interface IDateLogicToggleProps {\r\n value?: IFilterDateLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterDateLogic) => void\r\n}\r\n\r\nexport const DateLogicToggle: FC<IDateLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterDateLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'before'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='before' aria-label='before date'>\r\n before\r\n </ToggleButton>\r\n <ToggleButton size='small' value='after' aria-label='after date'>\r\n after\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nexport interface IDateRangeLogicToggleProps {\r\n value?: IFilterDateRangeLogic\r\n onChange?: (event: React.MouseEvent<HTMLElement>, value: IFilterDateRangeLogic) => void\r\n}\r\n\r\nexport const DateRangeLogicToggle: FC<IDateRangeLogicToggleProps> = (props) => {\r\n const handleChange = (event: React.MouseEvent<HTMLElement>, newValue: string | null) => {\r\n if (newValue && props.onChange) {\r\n props.onChange(event, newValue as IFilterDateRangeLogic)\r\n }\r\n }\r\n\r\n return (\r\n <ToggleButtonGroupCustom size='small' value={props.value || 'between'} exclusive onChange={handleChange}>\r\n <ToggleButton size='small' value='between' aria-label='between dates'>\r\n between\r\n </ToggleButton>\r\n <ToggleButton size='small' value='not-between' aria-label='not between dates'>\r\n not between\r\n </ToggleButton>\r\n </ToggleButtonGroupCustom>\r\n )\r\n}\r\n\r\nconst ToggleButtonGroupCustom = styled(ToggleButtonGroup)({\r\n '& .MuiToggleButton-root': {\r\n color: '#fff',\r\n borderColor: 'rgba(255, 255, 255, 0.3)',\r\n fontSize: '0.65rem',\r\n fontWeight: 600,\r\n lineHeight: 1,\r\n minWidth: '40px',\r\n padding: '6px 8px',\r\n '&.Mui-selected': {\r\n backgroundColor: '#1976d2',\r\n color: '#fff',\r\n '&:hover': {\r\n backgroundColor: '#1565c0'\r\n }\r\n },\r\n '&:hover': {\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)'\r\n }\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Notes\r\nexport interface IFilterNotesProps {\r\n title?: string\r\n items?: string[]\r\n disabledSize?: boolean\r\n renderContent?: () => ReactNode\r\n}\r\n\r\nconst HelpTooltipContent: FC<{ items: string[] }> = (props) => (\r\n <WrapList>\r\n {props.items.map((item, index) => (\r\n <Typography key={index} component='li' variant='body2'>\r\n {item}\r\n </Typography>\r\n ))}\r\n </WrapList>\r\n)\r\n\r\nexport const FilterNotes: FC<IFilterNotesProps> = (props) => (\r\n <WrapIcon className={props.disabledSize === true ? 'disabled-size' : ''}>\r\n <HelpTooltip small title={props.title ?? 'The search includes'}>\r\n {props.renderContent ? props.renderContent() : <HelpTooltipContent items={props.items ?? []} />}\r\n </HelpTooltip>\r\n </WrapIcon>\r\n)\r\n//#endregion\r\n\r\n//#region Input\r\nexport const FilterInput = React.forwardRef<HTMLInputElement, InputBaseProps>((props, ref) => {\r\n return <InputBase fullWidth autoComplete='off' size='small' {...props} inputRef={ref} />\r\n})\r\n\r\ninterface IFilterInputAdornmentProps {\r\n notes?: IFilterNotesProps\r\n keyword?: string\r\n onClear: IconButtonProps['onClick']\r\n onEnterSearch: ButtonProps['onClick']\r\n}\r\n\r\nexport const FilterInputAdornment: FC<IFilterInputAdornmentProps> = (props) => (\r\n <InputAdornment position='end'>\r\n {props.keyword && (\r\n <>\r\n <HelpButton size='small' color='primary' onClick={props.onEnterSearch} sx={{ display: { xs: 'none', md: 'flex' } }}>\r\n <Typography variant='caption'>\r\n Type and hit <b>Enter ⏎</b> to filter.\r\n </Typography>\r\n </HelpButton>\r\n <Tooltip title='Press Enter to filter' placement='bottom' arrow>\r\n <IconButton size='small' color='primary' sx={{ display: { xs: 'flex', md: 'none' } }} onClick={props.onEnterSearch}>\r\n <KeyboardReturnIcon fontSize='small' />\r\n </IconButton>\r\n </Tooltip>\r\n </>\r\n )}\r\n {props.keyword && (\r\n <Tooltip title='Press Esc to clear' placement='bottom' arrow>\r\n <IconButton size='small' sx={{ marginLeft: '8px', color: 'text.error', '&:hover': { color: 'error.main' } }} onClick={props.onClear}>\r\n <CloseIcon fontSize='small' />\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {props.notes && <FilterNotes {...props.notes} />}\r\n </InputAdornment>\r\n)\r\n\r\nconst HelpButton = styled(Button)({\r\n padding: '4px 6px',\r\n textTransform: 'none',\r\n lineHeight: 1,\r\n '.MuiTypography-root': {\r\n fontWeight: 600,\r\n b: {\r\n fontWeight: 700,\r\n backgroundColor: colors.blue[100],\r\n borderRadius: '4px',\r\n padding: '2px 4px'\r\n }\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Button\r\nexport interface IButtonClearProps {\r\n visibled?: boolean\r\n onClick: IconButtonProps['onClick']\r\n}\r\n\r\nexport const ButtonClear: FC<IButtonClearProps> = (props) => (\r\n <WrapIcon>\r\n <Tooltip title='Remove filter'>\r\n <Fade in={props.visibled} unmountOnExit>\r\n <IconButton size='small' onClick={props.onClick}>\r\n <CloseIcon fontSize='small' />\r\n </IconButton>\r\n </Fade>\r\n </Tooltip>\r\n </WrapIcon>\r\n)\r\n\r\nexport const ClearAllButton = React.forwardRef<HTMLButtonElement, ButtonProps>(({ children, ...props }, ref) => (\r\n <ClearButtonStyled size='small' color='error' startIcon={<ClearAllIcon />} ref={ref} {...props}>\r\n {children || 'Clear all'}\r\n </ClearButtonStyled>\r\n))\r\n\r\nconst ClearButtonStyled = styled(Button)({ textTransform: 'none', fontWeight: 700 })\r\n\r\nexport const FilterButton = React.forwardRef<HTMLButtonElement, IconButtonProps>((props, ref) => (\r\n <IconButton ref={ref} size='small' sx={{ flex: '0 0 auto' }} {...props}>\r\n <FilterListIcon />\r\n </IconButton>\r\n))\r\n\r\nexport const SortIconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>((props, ref) => (\r\n <IconButton ref={ref} size='small' sx={{ flex: '0 0 auto' }} {...props}>\r\n <ShuffleIcon />\r\n </IconButton>\r\n))\r\n\r\nexport const SortButton: FC<ButtonProps> = (props) => (\r\n <>\r\n {mapDataViewContext((context) => {\r\n const { filterState, filterBarConfigs: configs } = context\r\n const config: Partial<{ title: string; icon: ReactNode }> = filterState.sort ? mapSortConfigs[filterState.sort?.direction] : {}\r\n const fieldConfig = configs.fields?.[filterState.sort?.field as any]\r\n const text = fieldConfig?.label || filterState.sort?.field.toString() || configs.sortButton?.text\r\n return (\r\n <SortButtonStyled\r\n size='small'\r\n color='inherit'\r\n startIcon={config.icon || <ShuffleIcon fontSize='small' />}\r\n endIcon={configs.sortButton?.icon ?? <KeyboardArrowDownIcon fontSize='small' />}\r\n onClick={(e) => context.onPopperPanelChange(e.currentTarget, 'sortButton')}\r\n {...configs.sortButton?.wrapProps}\r\n {...props}\r\n >\r\n {text || 'Sort'}\r\n </SortButtonStyled>\r\n )\r\n })}\r\n </>\r\n)\r\n\r\nconst SortButtonStyled = styled(Button)({\r\n height: 'var(--filter-bar-height, 40px)',\r\n padding: '0 16px',\r\n backgroundColor: colors.grey[50],\r\n border: '1px solid var(--color-divider, rgba(145 158 171 / 20%))',\r\n textTransform: 'none',\r\n fontWeight: 600,\r\n ':hover': {\r\n backgroundColor: colors.grey[100]\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Panel Not Found\r\nexport const PanelNotFound: FC<{ area?: string }> = ({ area }) => (\r\n <Box sx={{ padding: '8px', textAlign: 'center', border: '1px solid #ddd', borderRadius: '4px' }}>\r\n <Typography variant='body2' sx={{ padding: '8px' }}>\r\n No panel available for area: {area}\r\n </Typography>\r\n </Box>\r\n)\r\n//#endregion\r\n\r\n//#region Form\r\ninterface IFormContentProps {\r\n label: string\r\n notes?: any\r\n children?: React.ReactNode\r\n afterTopBar?: React.ReactNode\r\n}\r\n\r\nconst FormContent: FC<IFormContentProps> = ({ label, notes, children, afterTopBar }) => (\r\n <FormContentWrapper>\r\n <Box className='top-bar'>\r\n <Typography variant='subtitle2'>{label}</Typography>\r\n {afterTopBar && <Box className='after-top-bar'>{afterTopBar}</Box>}\r\n {notes && <FilterNotes title={`The ${label} includes`} disabledSize {...notes} />}\r\n </Box>\r\n <Box className='content'>{children}</Box>\r\n </FormContentWrapper>\r\n)\r\n\r\nconst FormContentWrapper = styled(Box)({\r\n minWidth: '200px',\r\n borderRadius: '4px',\r\n overflow: 'hidden',\r\n '.top-bar': {\r\n display: 'flex',\r\n alignItems: 'center',\r\n background: colors.grey[900],\r\n padding: '8px',\r\n gap: '8px',\r\n '.MuiTypography-root': {\r\n color: colors.common.white,\r\n flex: 1\r\n }\r\n },\r\n '.after-top-bar': {\r\n marginLeft: '8px'\r\n },\r\n '.content': {\r\n padding: '8px'\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Menu - String Type\r\ninterface IMenuWithTypeBaseProps {\r\n name: string\r\n validationResult?: IValidationResult\r\n}\r\n\r\ninterface IMenuWithTypeStringProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterBasicDef\r\n}\r\n\r\nexport const MenuWithTypeString: FC<IMenuWithTypeStringProps> = (props) => {\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent label={label} notes={props.fieldConfig?.notes}>\r\n <TextField\r\n autoFocus\r\n name={props.name}\r\n size='small'\r\n fullWidth\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n />\r\n </FormContent>\r\n )\r\n}\r\n//#endregion\r\n\r\n//#region Menu - Select Type\r\nexport interface IMenuWithTypeSelectProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterSelectDef\r\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void\r\n}\r\n\r\nexport const MenuWithTypeSelect: FC<IMenuWithTypeSelectProps> = (props) => {\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent label={label} notes={props.fieldConfig?.notes}>\r\n <CustomRadioGroup name={props.name} className={props.validationResult?.hasError ? 'error' : ''} onChange={props.onChange}>\r\n {props.fieldConfig?.options.map((x, i) => (\r\n <FormControlLabel key={x.value.toString() + i} value={x.value} control={<Radio />} label={x.label ?? x.value} />\r\n ))}\r\n </CustomRadioGroup>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst CustomRadioGroup = styled(RadioGroup)({\r\n marginLeft: '-8px',\r\n marginRight: '-8px',\r\n '&.error .MuiRadio-root': {\r\n color: '#d32f2f'\r\n },\r\n '.MuiFormControlLabel-root': {\r\n margin: 0\r\n },\r\n '.MuiFormControlLabel-root:hover': {\r\n backgroundColor: 'rgba(25, 118, 210, 0.04)'\r\n }\r\n})\r\n//#endregion\r\n\r\n//#region Menu - Select Multi Type\r\nexport interface IMenuWithTypeSelectMultiProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterSelectDef\r\n onChange?: (event: React.SyntheticEvent, checked: boolean) => void\r\n}\r\n\r\nexport const MenuWithTypeSelectMulti: FC<IMenuWithTypeSelectMultiProps> = (props) => {\r\n const [filterLogic, setFilterLogic] = useState<IFilterLogic>('and')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<FilterLogicToggle value={filterLogic} onChange={(_, value) => setFilterLogic(value)} />}\r\n >\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='filterLogic' value={filterLogic} />\r\n <CustomFormGroup className={props.validationResult?.hasError ? 'error' : ''}>\r\n {props.fieldConfig?.options.map((x, i) => (\r\n <FormControlLabel\r\n key={x.value.toString() + i}\r\n value={x.value}\r\n control={<Checkbox name={props.name} />}\r\n label={x.label ?? x.value}\r\n onChange={props.onChange}\r\n />\r\n ))}\r\n </CustomFormGroup>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst CustomFormGroup = styled(FormGroup)({\r\n marginLeft: '-8px',\r\n marginRight: '-8px',\r\n '&.error .MuiCheckbox-root': {\r\n color: '#d32f2f'\r\n },\r\n '.MuiFormControlLabel-root': {\r\n margin: 0\r\n },\r\n '.MuiFormControlLabel-root:hover': {\r\n backgroundColor: 'rgba(25, 118, 210, 0.04)'\r\n }\r\n})\r\n//#endregion\r\n\r\nfunction convertDateToCustomFormat(dateString: string): string {\r\n if (!dateString || !/^\\d{4}-\\d{2}-\\d{2}$/.test(dateString)) return ''\r\n return `${dateString}T00:00:00.0000000`\r\n}\r\n//#region Menu - Date Type\r\nexport interface IMenuWithTypeDateProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterDateDef\r\n}\r\n\r\nexport const MenuWithTypeDate: FC<IMenuWithTypeDateProps> = (props) => {\r\n const [dateLogic, setDateLogic] = useState<IFilterDateLogic>('before')\r\n const [value, setValue] = useState<string>('')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<DateLogicToggle value={dateLogic} onChange={(_, value) => setDateLogic(value)} />}\r\n >\r\n <Box className='content'>\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='dateLogic' value={dateLogic} />\r\n <input hidden type='text' name={props.name} readOnly value={convertDateToCustomFormat(value)} />\r\n <TextField\r\n autoFocus\r\n fullWidth\r\n type='date'\r\n size='small'\r\n value={value}\r\n onChange={(event) => setValue(event.target.value)}\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n </Box>\r\n </FormContent>\r\n )\r\n}\r\n//#endregion\r\n\r\n//#region Menu - Date Range Type\r\nexport interface IMenuWithTypeDateRangeProps extends IMenuWithTypeBaseProps {\r\n fieldConfig?: IFilterDateDef\r\n}\r\n\r\nexport const MenuWithTypeDateRange: FC<IMenuWithTypeDateRangeProps> = (props) => {\r\n const [dateRangeLogic, setDateRangeLogic] = useState<IFilterDateRangeLogic>('between')\r\n const label = props.fieldConfig?.label ?? props.name\r\n return (\r\n <FormContent\r\n label={label}\r\n notes={props.fieldConfig?.notes}\r\n afterTopBar={<DateRangeLogicToggle value={dateRangeLogic} onChange={(_, value) => setDateRangeLogic(value)} />}\r\n >\r\n {/* Hidden input for logic value */}\r\n <input type='hidden' name='dateRangeLogic' value={dateRangeLogic} />\r\n <DateRangeContainer>\r\n <TextField\r\n autoFocus\r\n fullWidth\r\n name={`${props.name}_start`}\r\n type='date'\r\n size='small'\r\n label='From'\r\n error={!!props.validationResult?.hasError}\r\n sx={{ marginBottom: 1 }}\r\n InputLabelProps={{ shrink: true }}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n <TextField\r\n fullWidth\r\n name={`${props.name}_end`}\r\n type='date'\r\n size='small'\r\n label='To'\r\n error={!!props.validationResult?.hasError}\r\n helperText={props.validationResult?.message}\r\n InputLabelProps={{ shrink: true }}\r\n inputProps={{ min: props.fieldConfig?.minDate, max: props.fieldConfig?.maxDate }}\r\n />\r\n </DateRangeContainer>\r\n </FormContent>\r\n )\r\n}\r\n\r\nconst DateRangeContainer = styled(Box)({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px'\r\n})\r\n//#endregion\r\n\r\n//#region Styled\r\nconst WrapIcon = styled(Box)({\r\n display: 'inline-flex',\r\n flex: '0 0 auto',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n '&:not(.disabled-size)': {\r\n width: '40px',\r\n height: '40px'\r\n }\r\n})\r\n\r\nconst WrapList = styled('ul')({\r\n paddingLeft: '1.7rem',\r\n marginBottom: 0,\r\n li: {\r\n position: 'relative',\r\n textAlign: 'justify',\r\n '&::before': {\r\n content: '\"►\"',\r\n display: 'block',\r\n position: 'absolute',\r\n top: '50%',\r\n right: 'calc(100% + 6px)',\r\n transform: 'translateY(-50%)',\r\n fontSize: '0.9em'\r\n }\r\n }\r\n})\r\n//#endregion\r\n"],"names":["mapSortConfigs","asc","title","icon","_jsx","ArrowUpwardIcon","fontSize","desc","ArrowDownwardIcon","FilterLogicToggle","props","_jsxs","ToggleButtonGroupCustom","size","value","exclusive","onChange","event","newValue","children","ToggleButton","DateLogicToggle","DateRangeLogicToggle","styled","ToggleButtonGroup","color","borderColor","fontWeight","lineHeight","minWidth","padding","backgroundColor","HelpTooltipContent","WrapList","items","map","item","index","Typography","component","variant","FilterNotes","_props$title","_props$items","WrapIcon","className","disabledSize","HelpTooltip","small","renderContent","FilterInput","React","forwardRef","ref","InputBase","_objectSpread","fullWidth","autoComplete","inputRef","FilterInputAdornment","InputAdornment","position","keyword","_Fragment","HelpButton","onClick","onEnterSearch","sx","display","xs","md","Tooltip","placement","arrow","IconButton","KeyboardReturnIcon","marginLeft","onClear","CloseIcon","notes","Button","textTransform","b","colors","blue","borderRadius","ClearAllButton","_ref","_objectWithoutProperties","_excluded","ClearButtonStyled","startIcon","ClearAllIcon","FilterButton","flex","FilterListIcon","SortButton","mapDataViewContext","context","_filterState$sort","_configs$fields","_filterState$sort2","_filterState$sort3","_configs$sortButton","_configs$sortButton$i","_configs$sortButton2","_configs$sortButton3","filterState","configs","filterBarConfigs","config","sort","direction","fieldConfig","fields","field","text","label","toString","sortButton","SortButtonStyled","ShuffleIcon","endIcon","KeyboardArrowDownIcon","e","onPopperPanelChange","currentTarget","wrapProps","height","grey","border","PanelNotFound","_ref2","area","Box","textAlign","FormContent","_ref3","afterTopBar","FormContentWrapper","concat","overflow","alignItems","background","gap","common","white","MenuWithTypeString","_props$fieldConfig$la","_props$fieldConfig","_props$fieldConfig2","_props$validationResu","_props$validationResu2","name","TextField","autoFocus","error","validationResult","hasError","helperText","message","MenuWithTypeSelect","_props$fieldConfig$la2","_props$fieldConfig3","_props$fieldConfig4","_props$validationResu3","_props$fieldConfig5","CustomRadioGroup","options","x","i","_x$label","FormControlLabel","control","Radio","RadioGroup","marginRight","margin","MenuWithTypeSelectMulti","_props$fieldConfig$la3","_props$fieldConfig6","_props$fieldConfig7","_props$validationResu4","_props$fieldConfig8","_useState","useState","_useState2","_slicedToArray","filterLogic","setFilterLogic","_","type","CustomFormGroup","_x$label2","Checkbox","FormGroup","MenuWithTypeDate","_props$fieldConfig$la4","_props$fieldConfig9","_props$fieldConfig0","_props$validationResu5","_props$validationResu6","_props$fieldConfig1","_props$fieldConfig10","dateString","_useState3","_useState4","dateLogic","setDateLogic","_useState5","_useState6","setValue","hidden","readOnly","test","target","inputProps","min","minDate","max","maxDate","MenuWithTypeDateRange","_props$fieldConfig$la5","_props$fieldConfig11","_props$fieldConfig12","_props$validationResu7","_props$fieldConfig13","_props$fieldConfig14","_props$validationResu8","_props$validationResu9","_props$fieldConfig15","_props$fieldConfig16","_useState7","_useState8","dateRangeLogic","setDateRangeLogic","DateRangeContainer","marginBottom","InputLabelProps","shrink","flexDirection","justifyContent","width","paddingLeft","li","content","top","right","transform"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{CancelAction,default as ServiceBase}from"./base/service-base.js";export{HttpService,createHttpService}from"./base/gateway.js";export{default as CRUDServiceBase}from"./base/crud-service-base.js";export{processError}from"./base/helpers.js";export{default as GraphqlRequest,createGraphqlRequest}from"./graphql/graphql-request.js";export{EAppName}from"./graphql/types.js";export{RequestParam,createRequestBuilder}from"./graphql/request-param.js";export{createKeyConverter,getKeyConverter}from"./graphql/key-converter.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{slicedToArray as r,asyncToGenerator as n,objectSpread2 as e,regenerator as i}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as o,Fragment as a}from"react/jsx-runtime";import{useState as t,useEffect as u}from"react";import{mfeBridge as s}from"./mfe-bridge.js";import{INITIAL_AUTH_STATE as l,AUTH_CHANNELS as c}from"./auth.types.js";import{isBrowser as d}from"./environment.js";var f=function(f){var p=f.children,h=f.onLogin,v=f.onLogout,b=f.initialState,m=void 0===b?l:b,g=f.authData,A=f.onAuthChange,E=t(m),T=r(E,2),L=T[0],w=T[1];u((function(){if(g){var r=null;(g.id||g.displayName)&&(r={id:g.id||"unknown",displayName:g.displayName||"Unknown User",email:g.email||"",roles:g.roles||[],avatar:g.avatar});var n={isAuthenticated:!!g.id||!!g.displayName,isLoading:!1,user:r,error:null,serverRendered:!d()};w(n),s.publish(c.STATE_CHANGE,n)}}),[g]),u((function(){if(A)return A((function(r){w(r),s.publish(c.STATE_CHANGE,r)}))}),[A]),u((function(){var r=s.subscribe(c.REQUEST_STATE,(function(){s.publish(c.STATE_CHANGE,L)})),n=s.subscribe(c.LOGIN,(function(r){N(r.username,r.password)})),e=s.subscribe(c.LOGOUT,(function(){S()}));return function(){r(),n(),e()}}),[L]);var N=function(){var r=n(i().m((function r(n,o){var a,t,u,l,f;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0,error:null})})),r.p=1,!h){r.n=3;break}return r.n=2,h({username:n,password:o});case 2:(a=r.v)?(t={isAuthenticated:a.isAuthenticated,isLoading:!1,user:a.user||null,error:a.error||null,serverRendered:!d()},w(t),s.publish(c.STATE_CHANGE,t)):w((function(r){return e(e({},r),{},{isLoading:!1})})),r.n=4;break;case 3:throw new Error("No login handler provided. Please provide an onLogin handler to AuthProvider.");case 4:r.n=6;break;case 5:r.p=5,f=r.v,u=f instanceof Error?f.message:"Login failed",l={isAuthenticated:!1,isLoading:!1,user:null,error:u,serverRendered:!d()},w(l),s.publish(c.STATE_CHANGE,l);case 6:return r.a(2)}}),r,null,[[1,5]])})));return function(n,e){return r.apply(this,arguments)}}(),S=function(){var r=n(i().m((function r(){var n,o,a;return i().w((function(r){for(;;)switch(r.n){case 0:if(w((function(r){return e(e({},r),{},{isLoading:!0})})),r.p=1,!v){r.n=5;break}return r.n=2,v();case 2:if(!1===r.v){r.n=3;break}n={isAuthenticated:!1,isLoading:!1,user:null,error:null,serverRendered:!d()},w(n),s.publish(c.STATE_CHANGE,n),r.n=4;break;case 3:throw new Error("Logout failed");case 4:r.n=6;break;case 5:throw new Error("No logout handler provided. Please provide an onLogout handler to AuthProvider.");case 6:r.n=8;break;case 7:r.p=7,a=r.v,o=a instanceof Error?a.message:"Logout failed",w((function(r){return e(e({},r),{},{isLoading:!1,error:o})}));case 8:return r.a(2)}}),r,null,[[1,7]])})));return function(){return r.apply(this,arguments)}}();return o(a,{children:p})};function p(){var n=t(l),i=r(n,2),o=i[0],a=i[1];u((function(){var r=s.subscribe(c.STATE_CHANGE,(function(r){a(r)}));return s.publish(c.REQUEST_STATE,null),r}),[]);return e(e({},o),{},{login:function(r,n){s.publish(c.LOGIN,{username:r,password:n})},logout:function(){s.publish(c.LOGOUT,null)}})}export{f as AuthProvider,p as useAuth};
|
|
2
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sources":["../../src/mfe-shared/auth.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { AUTH_CHANNELS, AuthState, INITIAL_AUTH_STATE, User } from './auth.types'\r\nimport { isBrowser } from './environment'\r\n\r\ninterface ILoginParams {\r\n username: string\r\n password: string\r\n}\r\n\r\ninterface ILoginResponse {\r\n isAuthenticated: boolean\r\n user?: User\r\n error?: string\r\n}\r\n\r\nexport interface IAuthProviderProps {\r\n children?: React.ReactNode\r\n\r\n // Custom handlers for manual authentication\r\n // onLogin can simply trigger authentication (like opening a login modal) without returning immediate data\r\n onLogin?: (params: ILoginParams) => Promise<ILoginResponse | void>\r\n onLogout?: () => Promise<boolean | void>\r\n\r\n // Initial state\r\n initialState?: AuthState\r\n\r\n // Direct auth data - allows updating state directly from external sources\r\n // Main approach for real-world applications with their own authentication services\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any // Allow custom fields\r\n }\r\n\r\n // Auth state subscription\r\n // Allows registering callbacks to receive notifications when auth state changes from external services\r\n onAuthChange?: (callback: (newState: AuthState) => void) => () => void\r\n}\r\n\r\n/**\r\n * AuthProvider - Component for Host application\r\n *\r\n * Manages authentication state and broadcasts events to MFEs.\r\n * Place this component anywhere in your application, no need to wrap other components.\r\n *\r\n * Host can customize login/logout behavior by providing custom handlers.\r\n */\r\nexport const AuthProvider: React.FC<IAuthProviderProps> = ({\r\n children,\r\n onLogin,\r\n onLogout,\r\n initialState = INITIAL_AUTH_STATE,\r\n authData,\r\n onAuthChange\r\n}) => {\r\n // Authentication state\r\n const [authState, setAuthState] = useState<AuthState>(initialState)\r\n\r\n // Handle when authData is provided directly and changes\r\n useEffect(() => {\r\n if (authData) {\r\n // Convert from authData to AuthState\r\n\r\n let user: User | null = null\r\n if (authData.id || authData.displayName) {\r\n user = {\r\n id: authData.id || 'unknown',\r\n displayName: authData.displayName || 'Unknown User',\r\n email: authData.email || '',\r\n roles: authData.roles || [],\r\n avatar: authData.avatar\r\n }\r\n }\r\n const isAuthenticated = !!authData.id || !!authData.displayName\r\n const newState: AuthState = { \r\n isAuthenticated, \r\n isLoading: false, \r\n user, \r\n error: null,\r\n // Mark if running in SSR environment\r\n serverRendered: !isBrowser()\r\n }\r\n // Update state and notify MFEs\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n }\r\n }, [authData]) // Re-run when authData changes\r\n\r\n // Register with onAuthChange if provided\r\n useEffect(() => {\r\n if (onAuthChange) {\r\n // Register callback to receive notifications when auth changes from external service\r\n const unsubscribe = onAuthChange((newState) => {\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n })\r\n\r\n return unsubscribe\r\n }\r\n }, [onAuthChange])\r\n\r\n useEffect(() => {\r\n // Listen for requests from MFEs\r\n const unsubscribeRequestState = mfeBridge.subscribe(AUTH_CHANNELS.REQUEST_STATE, () => {\r\n // Send current state when requested by an MFE\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, authState)\r\n })\r\n\r\n const unsubscribeLogin = mfeBridge.subscribe(AUTH_CHANNELS.LOGIN, (credentials) => {\r\n handleLogin(credentials.username, credentials.password)\r\n })\r\n\r\n const unsubscribeLogout = mfeBridge.subscribe(AUTH_CHANNELS.LOGOUT, () => {\r\n handleLogout()\r\n })\r\n\r\n return () => {\r\n unsubscribeRequestState()\r\n unsubscribeLogin()\r\n unsubscribeLogout()\r\n }\r\n }, [authState])\r\n\r\n // Login handler - uses onLogin from props if provided\r\n const handleLogin = async (username: string, password: string) => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true, error: null }))\r\n\r\n try {\r\n // Use provided login handler if available\r\n if (onLogin) {\r\n const result = await onLogin({ username, password })\r\n \r\n // If onLogin returns login response data, use it to update state\r\n if (result) {\r\n const newState: AuthState = {\r\n isAuthenticated: result.isAuthenticated,\r\n isLoading: false,\r\n user: result.user || null,\r\n error: result.error || null,\r\n serverRendered: !isBrowser()\r\n }\r\n \r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n // If onLogin doesn't return data, just set loading to false\r\n // This allows the host app to handle the auth flow completely\r\n setAuthState(prev => ({ ...prev, isLoading: false }))\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No login handler provided. Please provide an onLogin handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Login failed'\r\n const errorState: AuthState = { \r\n isAuthenticated: false, \r\n isLoading: false, \r\n user: null, \r\n error: message,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(errorState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, errorState)\r\n }\r\n }\r\n\r\n // Logout handler - uses onLogout from props if provided\r\n const handleLogout = async () => {\r\n setAuthState((prev) => ({ ...prev, isLoading: true }))\r\n\r\n try {\r\n // Use provided logout handler if available\r\n if (onLogout) {\r\n const result = await onLogout()\r\n \r\n // If onLogout returns a boolean, use it to determine success\r\n // If it returns nothing (void), assume success\r\n if (result !== false) {\r\n const newState: AuthState = { \r\n isAuthenticated: false, \r\n isLoading: false, \r\n user: null, \r\n error: null,\r\n serverRendered: !isBrowser()\r\n }\r\n setAuthState(newState)\r\n mfeBridge.publish(AUTH_CHANNELS.STATE_CHANGE, newState)\r\n } else {\r\n throw new Error('Logout failed')\r\n }\r\n } else {\r\n // No default handling in library mode\r\n throw new Error('No logout handler provided. Please provide an onLogout handler to AuthProvider.')\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Logout failed'\r\n setAuthState((prev) => ({ ...prev, isLoading: false, error: message }))\r\n }\r\n }\r\n\r\n // Simply return children\r\n return <>{children}</>\r\n}\r\n\r\n// Hook for using Auth in both host and MFE\r\nexport function useAuth() {\r\n const [authState, setAuthState] = useState<AuthState>(INITIAL_AUTH_STATE)\r\n\r\n useEffect(() => {\r\n // Subscribe to authentication state changes from provider\r\n const unsubscribe = mfeBridge.subscribe<AuthState>(AUTH_CHANNELS.STATE_CHANGE, (newState) => {\r\n setAuthState(newState)\r\n })\r\n\r\n // Request current state\r\n mfeBridge.publish(AUTH_CHANNELS.REQUEST_STATE, null)\r\n\r\n return unsubscribe\r\n }, [])\r\n\r\n // Functions always use mfeBridge for communication\r\n const login = (username: string, password: string) => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGIN, { username, password })\r\n }\r\n\r\n const logout = () => {\r\n mfeBridge.publish(AUTH_CHANNELS.LOGOUT, null)\r\n }\r\n\r\n return { ...authState, login, logout }\r\n}\r\n"],"names":["AuthProvider","_ref","children","onLogin","onLogout","_ref$initialState","initialState","INITIAL_AUTH_STATE","authData","onAuthChange","_useState","useState","_useState2","_slicedToArray","authState","setAuthState","useEffect","user","id","displayName","email","roles","avatar","newState","isAuthenticated","isLoading","error","serverRendered","isBrowser","mfeBridge","publish","AUTH_CHANNELS","STATE_CHANGE","unsubscribeRequestState","subscribe","REQUEST_STATE","unsubscribeLogin","LOGIN","credentials","handleLogin","username","password","unsubscribeLogout","LOGOUT","handleLogout","_ref2","_asyncToGenerator","_regenerator","m","_callee","result","message","errorState","_t","w","_context","n","prev","_objectSpread","p","v","Error","a","_x","_x2","apply","this","arguments","_ref3","_callee2","_t2","_context2","_jsx","_Fragment","useAuth","_useState3","_useState4","unsubscribe","login","logout"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{objectSpread2 as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t}from"react/jsx-runtime";import{INITIAL_AUTH_STATE as e}from"./auth.types.js";import{AuthProvider as o}from"./auth.js";import{HydrationGuard as a}from"./hydration-helper.js";var n=function(n){var i=n.children,u=n.initialAuthState,h=n.userData,l=n.authData,s=n.onLogin,d=n.onLogout,m=n.onAuthChange,p=u;return!p&&h&&(p={isAuthenticated:!0,isLoading:!1,user:h,error:null,serverRendered:!0}),t(o,{initialState:p||r(r({},e),{},{serverRendered:!0}),authData:l,onLogin:s,onLogout:d,onAuthChange:m,children:t(a,{children:i})})};export{n as SsrAuthProvider};
|
|
2
|
+
//# sourceMappingURL=auth.ssr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.ssr.js","sources":["../../src/mfe-shared/auth.ssr.tsx"],"sourcesContent":["import React from 'react'\r\nimport { AuthState, INITIAL_AUTH_STATE, User } from './auth.types'\r\nimport { AuthProvider, type IAuthProviderProps } from './auth'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible auth provider\r\n */\r\ninterface ISsrAuthProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial auth state for SSR */\r\n initialAuthState?: AuthState\r\n /** User data for initial state */\r\n userData?: User\r\n /** Custom auth data to be passed to AuthProvider */\r\n authData?: {\r\n id?: string\r\n displayName?: string\r\n email?: string\r\n avatar?: string\r\n roles?: string[]\r\n [key: string]: any\r\n }\r\n /** Custom login handler */\r\n onLogin?: IAuthProviderProps['onLogin']\r\n /** Custom logout handler */\r\n onLogout?: IAuthProviderProps['onLogout']\r\n /** Auth state change subscription */\r\n onAuthChange?: IAuthProviderProps['onAuthChange']\r\n}\r\n\r\n/**\r\n * Auth provider component that supports SSR\r\n * \r\n * This component allows providing initial auth data during server-side rendering\r\n * and then hydrating from API or other sources once client-side.\r\n */\r\nexport const SsrAuthProvider: React.FC<ISsrAuthProviderProps> = ({\r\n children,\r\n initialAuthState,\r\n userData,\r\n authData,\r\n onLogin,\r\n onLogout,\r\n onAuthChange\r\n}) => {\r\n // Prepare auth state for SSR\r\n let ssrAuthState = initialAuthState\r\n \r\n // If userData is provided but not initialAuthState, create auth state from userData\r\n if (!ssrAuthState && userData) {\r\n ssrAuthState = {\r\n isAuthenticated: true,\r\n isLoading: false,\r\n user: userData,\r\n error: null,\r\n serverRendered: true\r\n }\r\n }\r\n\r\n return (\r\n <AuthProvider\r\n initialState={ssrAuthState || { ...INITIAL_AUTH_STATE, serverRendered: true }}\r\n authData={authData}\r\n onLogin={onLogin}\r\n onLogout={onLogout}\r\n onAuthChange={onAuthChange}\r\n >\r\n <HydrationGuard>\r\n {children}\r\n </HydrationGuard>\r\n </AuthProvider>\r\n )\r\n}\r\n\r\n/**\r\n * Props for the SSR-compatible authenticated content component\r\n */\r\ninterface IAuthenticatedContentProps {\r\n /** Content to show when authenticated */\r\n children: React.ReactNode\r\n /** Content to show when not authenticated */\r\n fallback?: React.ReactNode\r\n /** Initial authentication state for SSR */\r\n initiallyAuthenticated?: boolean\r\n}\r\n\r\n/**\r\n * Component that conditionally renders content based on authentication state\r\n * with SSR support\r\n */\r\nexport const AuthenticatedContent: React.FC<IAuthenticatedContentProps> = ({\r\n children,\r\n fallback,\r\n initiallyAuthenticated = false\r\n}) => {\r\n // Let the AuthProvider handle hydration - we just need to render the right content\r\n return (\r\n <HydrationGuard\r\n serverFallback={initiallyAuthenticated ? <>{children}</> : <>{fallback}</>}\r\n >\r\n {/* Regular content will be rendered during hydration and after */}\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrAuthProvider","_ref","children","initialAuthState","userData","authData","onLogin","onLogout","onAuthChange","ssrAuthState","isAuthenticated","isLoading","user","error","serverRendered","_jsx","AuthProvider","initialState","_objectSpread","INITIAL_AUTH_STATE","HydrationGuard"],"mappings":"0QAsCaA,EAAmD,SAApCC,GAQvB,IAPHC,EAAQD,EAARC,SACAC,EAAgBF,EAAhBE,iBACAC,EAAQH,EAARG,SACAC,EAAQJ,EAARI,SACAC,EAAOL,EAAPK,QACAC,EAAQN,EAARM,SACAC,EAAYP,EAAZO,aAGIC,EAAeN,EAanB,OAVKM,GAAgBL,IACnBK,EAAe,CACbC,iBAAiB,EACjBC,WAAW,EACXC,KAAMR,EACNS,MAAO,KACPC,gBAAgB,IAKlBC,EAACC,GACCC,aAAcR,GAAYS,EAAAA,KAASC,GAAkB,GAAA,CAAEL,gBAAgB,IACvET,SAAUA,EACVC,QAASA,EACTC,SAAUA,EACVC,aAAcA,EAAYN,SAE1Ba,EAACK,EAAc,CAAAlB,SACZA,KAIT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={STATE_CHANGE:"mfe:auth:state_change",REQUEST_STATE:"mfe:auth:request_state",LOGIN:"mfe:auth:login",LOGOUT:"mfe:auth:logout"},t={isAuthenticated:!1,isLoading:!1,user:null,error:null,serverRendered:!1};export{e as AUTH_CHANNELS,t as INITIAL_AUTH_STATE};
|
|
2
|
+
//# sourceMappingURL=auth.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.types.js","sources":["../../src/mfe-shared/auth.types.ts"],"sourcesContent":["/**\r\n * auth.types.ts - Type definitions for Authentication System\r\n * \r\n * This file defines the data structures and communication channels\r\n * for the micro-frontend authentication system.\r\n */\r\n\r\n/**\r\n * User data structure\r\n */\r\nexport type User = {\r\n /** Unique identifier for the user */\r\n id: string;\r\n /** User's display name */\r\n displayName: string;\r\n /** User's email address */\r\n email: string;\r\n /** Optional URL to user's avatar image */\r\n avatar?: string;\r\n /** List of roles/permissions assigned to the user */\r\n roles: string[];\r\n}\r\n\r\n/**\r\n * Authentication state structure\r\n */\r\nexport type AuthState = {\r\n /** Whether the user is currently authenticated */\r\n isAuthenticated: boolean;\r\n /** Whether an authentication operation is in progress */\r\n isLoading: boolean;\r\n /** The authenticated user, or null if not authenticated */\r\n user: User | null;\r\n /** Error message if authentication failed, or null */\r\n error: string | null;\r\n /** Whether the auth state was rendered on the server */\r\n serverRendered?: boolean;\r\n}\r\n\r\n/**\r\n * Communication channels between auth provider and consumers\r\n */\r\nexport const AUTH_CHANNELS = {\r\n /** Provider → Consumer: Notify when auth state changes */\r\n STATE_CHANGE: 'mfe:auth:state_change',\r\n /** Consumer → Provider: Request the current auth state */\r\n REQUEST_STATE: 'mfe:auth:request_state',\r\n /** Consumer → Provider: Request to log in */\r\n LOGIN: 'mfe:auth:login',\r\n /** Consumer → Provider: Request to log out */\r\n LOGOUT: 'mfe:auth:logout'\r\n}\r\n\r\n/**\r\n * Default authentication state - unauthenticated, not loading, no user, no error\r\n */\r\nexport const INITIAL_AUTH_STATE: AuthState = {\r\n isAuthenticated: false,\r\n isLoading: false,\r\n user: null,\r\n error: null,\r\n serverRendered: false\r\n}\r\n"],"names":["AUTH_CHANNELS","STATE_CHANGE","REQUEST_STATE","LOGIN","LOGOUT","INITIAL_AUTH_STATE","isAuthenticated","isLoading","user","error","serverRendered"],"mappings":"AA0CO,IAAMA,EAAgB,CAE3BC,aAAc,wBAEdC,cAAe,yBAEfC,MAAO,iBAEPC,OAAQ,mBAMGC,EAAgC,CAC3CC,iBAAiB,EACjBC,WAAW,EACXC,KAAM,KACNC,MAAO,KACPC,gBAAgB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{slicedToArray as r,toConsumableArray as t}from"../_virtual/_rollupPluginBabelHelpers.js";import{useState as e,useRef as n,useEffect as o,useCallback as i}from"react";import{mfeBridge as a}from"./mfe-bridge.js";import{isBrowser as c}from"./environment.js";var u="mfe_cart_items",s={ADD:"mfe:cart:add",REMOVE:"mfe:cart:remove",CLEAR:"mfe:cart:clear",INIT_REQUEST:"mfe:cart:init_request",INIT_RESPONSE:"mfe:cart:init_response",UPDATE:"mfe:cart:update"},l=function(){var i=e([]),l=r(i,2),f=l[0],m=l[1],E=n(!1);return o((function(){if(c()){var r=localStorage.getItem(u);if(r)try{var e=JSON.parse(r);Array.isArray(e)&&(m(e),E.current=!0)}catch(r){console.error("Failed to parse cart from localStorage:",r)}var n=a.subscribe(s.ADD,(function(r){console.log("Item added to cart:",r),m((function(e){var n=[].concat(t(e),[r]);return c()&&localStorage.setItem(u,JSON.stringify(n)),n}))})),o=a.subscribe(s.REMOVE,(function(r){m((function(t){var e=t.filter((function(t){return t.id!==r.id}));return c()&&localStorage.setItem(u,JSON.stringify(e)),e}))})),i=a.subscribe(s.CLEAR,(function(){m([]),c()&&localStorage.removeItem(u)})),l=a.subscribe(s.UPDATE,(function(r){m(r),c()&&localStorage.setItem(u,JSON.stringify(r))})),b=a.subscribe(s.INIT_REQUEST,(function(){f.length>0&&a.publish(s.INIT_RESPONSE,f)})),S=a.subscribe(s.INIT_RESPONSE,(function(r){!E.current&&r&&r.length>0&&(m(r),c()&&localStorage.setItem(u,JSON.stringify(r)),E.current=!0)}));return E.current||a.publish(s.INIT_REQUEST,null),function(){n(),o(),i(),l(),b(),S()}}}),[]),{items:f,totalItems:f.length}},f=function(){return{addToCart:i((function(r){a.publish(s.ADD,r)}),[]),removeFromCart:i((function(r){a.publish(s.REMOVE,{id:r})}),[]),clearCart:i((function(){a.publish(s.CLEAR,null)}),[]),updateCart:i((function(r){a.publish(s.UPDATE,r)}),[])}};export{s as CART_CHANNELS,f as useCartActions,l as useCartStore};
|
|
2
|
+
//# sourceMappingURL=cart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.js","sources":["../../src/mfe-shared/cart.tsx"],"sourcesContent":["/**\r\n * cart.tsx - Shared shopping cart system for micro-frontends\r\n * \r\n * This module provides hooks for managing a shared shopping cart across\r\n * multiple micro-frontends. The cart state is synchronized using the\r\n * mfeBridge communication system and persisted in localStorage.\r\n */\r\n\r\nimport { useEffect, useState, useRef, useCallback } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\n\r\n/** LocalStorage key for persisting cart items */\r\nconst CART_STORAGE_KEY = 'mfe_cart_items'\r\n\r\n/** Communication channels for cart operations */\r\nexport const CART_CHANNELS = {\r\n /** Add an item to the cart */\r\n ADD: 'mfe:cart:add',\r\n /** Remove an item from the cart */\r\n REMOVE: 'mfe:cart:remove',\r\n /** Clear all items from the cart */\r\n CLEAR: 'mfe:cart:clear',\r\n /** Request initial cart data (when a new MFE loads) */\r\n INIT_REQUEST: 'mfe:cart:init_request',\r\n /** Response with cart data (to initialize a new MFE) */\r\n INIT_RESPONSE: 'mfe:cart:init_response',\r\n /** Update the entire cart at once */\r\n UPDATE: 'mfe:cart:update'\r\n}\r\n\r\n/**\r\n * Shopping cart item structure\r\n */\r\nexport interface ICartItem {\r\n /** Unique identifier for the item */\r\n id: number\r\n /** Display name of the item */\r\n name: string\r\n /** Quantity of this item in the cart */\r\n quantity: number\r\n /** Price per unit of the item */\r\n price: number\r\n}\r\n\r\n/**\r\n * Hook to manage cart state across microFE\r\n * This hook will:\r\n * - Initialize cart from localStorage\r\n * - Listen for cart events (add, remove, clear, update)\r\n * - Provide current cart state\r\n */\r\nexport const useCartStore = () => {\r\n const [items, setItems] = useState<ICartItem[]>([])\r\n\r\n // Mark as initialized\r\n const initialized = useRef(false)\r\n\r\n useEffect(() => {\r\n // Skip localStorage operations in non-browser environments\r\n if (!isBrowser()) {\r\n return;\r\n }\r\n \r\n // Restore from localStorage if available\r\n const storedItems = localStorage.getItem(CART_STORAGE_KEY)\r\n if (storedItems) {\r\n try {\r\n const parsedItems = JSON.parse(storedItems)\r\n if (Array.isArray(parsedItems)) {\r\n setItems(parsedItems)\r\n initialized.current = true\r\n }\r\n } catch (e) {\r\n console.error('Failed to parse cart from localStorage:', e)\r\n }\r\n }\r\n\r\n // Subscribe to cart events\r\n const unsubAdd = mfeBridge.subscribe(CART_CHANNELS.ADD, (payload: ICartItem) => {\r\n console.log('Item added to cart:', payload)\r\n setItems((prev) => {\r\n const newItems = [...prev, payload]\r\n // Save to localStorage if in browser environment\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(newItems))\r\n }\r\n return newItems\r\n })\r\n })\r\n\r\n const unsubRemove = mfeBridge.subscribe(CART_CHANNELS.REMOVE, (payload: { id: number }) => {\r\n setItems((prev) => {\r\n const newItems = prev.filter((item) => item.id !== payload.id)\r\n // Save to localStorage if in browser environment\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(newItems))\r\n }\r\n return newItems\r\n })\r\n })\r\n\r\n const unsubClear = mfeBridge.subscribe(CART_CHANNELS.CLEAR, () => {\r\n setItems([])\r\n if (isBrowser()) {\r\n localStorage.removeItem(CART_STORAGE_KEY)\r\n }\r\n })\r\n\r\n const unsubUpdate = mfeBridge.subscribe(CART_CHANNELS.UPDATE, (payload: ICartItem[]) => {\r\n setItems(payload)\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(payload))\r\n }\r\n })\r\n\r\n // Subscribe to init requests from other microFEs\r\n const unsubInitReq = mfeBridge.subscribe(CART_CHANNELS.INIT_REQUEST, () => {\r\n // If state is already available, return it to other microFEs\r\n if (items.length > 0) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_RESPONSE, items)\r\n }\r\n })\r\n\r\n // Subscribe to init responses if state is not available\r\n const unsubInitRes = mfeBridge.subscribe(CART_CHANNELS.INIT_RESPONSE, (payload: ICartItem[]) => {\r\n if (!initialized.current && payload && payload.length > 0) {\r\n setItems(payload)\r\n if (isBrowser()) {\r\n localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(payload))\r\n }\r\n initialized.current = true\r\n }\r\n })\r\n\r\n // When mounted, send init request (only if no state from localStorage)\r\n if (!initialized.current) {\r\n mfeBridge.publish(CART_CHANNELS.INIT_REQUEST, null)\r\n }\r\n\r\n return () => {\r\n unsubAdd()\r\n unsubRemove()\r\n unsubClear()\r\n unsubUpdate()\r\n unsubInitReq()\r\n unsubInitRes()\r\n }\r\n }, [])\r\n\r\n return { items, totalItems: items.length }\r\n}\r\n\r\n/**\r\n * Hook to provide cart actions\r\n * This hook will:\r\n * - Only perform actions, not manage state\r\n * - Use mfeEventBridge to communicate with other microFEs\r\n * - Provide add, remove, clear, and update actions\r\n */\r\nexport const useCartActions = () => {\r\n // Add item to cart\r\n const addToCart = useCallback((item: ICartItem) => {\r\n mfeBridge.publish(CART_CHANNELS.ADD, item)\r\n }, [])\r\n\r\n // Remove item from cart\r\n const removeFromCart = useCallback((itemId: number) => {\r\n mfeBridge.publish(CART_CHANNELS.REMOVE, { id: itemId })\r\n }, [])\r\n\r\n // Clear cart\r\n const clearCart = useCallback(() => {\r\n mfeBridge.publish(CART_CHANNELS.CLEAR, null)\r\n }, [])\r\n\r\n // Update entire cart\r\n const updateCart = useCallback((items: ICartItem[]) => {\r\n mfeBridge.publish(CART_CHANNELS.UPDATE, items)\r\n }, [])\r\n\r\n return {\r\n addToCart,\r\n removeFromCart,\r\n clearCart,\r\n updateCart\r\n }\r\n}\r\n"],"names":["CART_STORAGE_KEY","CART_CHANNELS","ADD","REMOVE","CLEAR","INIT_REQUEST","INIT_RESPONSE","UPDATE","useCartStore","_useState","useState","_useState2","_slicedToArray","items","setItems","initialized","useRef","useEffect","isBrowser","storedItems","localStorage","getItem","parsedItems","JSON","parse","Array","isArray","current","e","console","error","unsubAdd","mfeBridge","subscribe","payload","log","prev","newItems","concat","_toConsumableArray","setItem","stringify","unsubRemove","filter","item","id","unsubClear","removeItem","unsubUpdate","unsubInitReq","length","publish","unsubInitRes","totalItems","useCartActions","addToCart","useCallback","removeFromCart","itemId","clearCart","updateCart"],"mappings":"sQAaA,IAAMA,EAAmB,iBAGZC,EAAgB,CAE3BC,IAAK,eAELC,OAAQ,kBAERC,MAAO,iBAEPC,aAAc,wBAEdC,cAAe,yBAEfC,OAAQ,mBAwBGC,EAAe,WAC1B,IAAAC,EAA0BC,EAAsB,IAAGC,EAAAC,EAAAH,EAAA,GAA5CI,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAGhBI,EAAcC,GAAO,GA8F3B,OA5FAC,GAAU,WAER,GAAKC,IAAL,CAKA,IAAMC,EAAcC,aAAaC,QAAQrB,GACzC,GAAImB,EACF,IACE,IAAMG,EAAcC,KAAKC,MAAML,GAC3BM,MAAMC,QAAQJ,KAChBR,EAASQ,GACTP,EAAYY,SAAU,EAEzB,CAAC,MAAOC,GACPC,QAAQC,MAAM,0CAA2CF,EAC1D,CAIH,IAAMG,EAAWC,EAAUC,UAAUhC,EAAcC,KAAK,SAACgC,GACvDL,QAAQM,IAAI,sBAAuBD,GACnCpB,GAAS,SAACsB,GACR,IAAMC,KAAQC,OAAAC,EAAOH,GAAMF,CAAAA,IAK3B,OAHIhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUJ,IAEjDA,CACT,GACF,IAEMK,EAAcV,EAAUC,UAAUhC,EAAcE,QAAQ,SAAC+B,GAC7DpB,GAAS,SAACsB,GACR,IAAMC,EAAWD,EAAKO,QAAO,SAACC,GAAI,OAAKA,EAAKC,KAAOX,EAAQW,MAK3D,OAHI3B,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUJ,IAEjDA,CACT,GACF,IAEMS,EAAad,EAAUC,UAAUhC,EAAcG,OAAO,WAC1DU,EAAS,IACLI,KACFE,aAAa2B,WAAW/C,EAE5B,IAEMgD,EAAchB,EAAUC,UAAUhC,EAAcM,QAAQ,SAAC2B,GAC7DpB,EAASoB,GACLhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUP,GAE1D,IAGMe,EAAejB,EAAUC,UAAUhC,EAAcI,cAAc,WAE/DQ,EAAMqC,OAAS,GACjBlB,EAAUmB,QAAQlD,EAAcK,cAAeO,EAEnD,IAGMuC,EAAepB,EAAUC,UAAUhC,EAAcK,eAAe,SAAC4B,IAChEnB,EAAYY,SAAWO,GAAWA,EAAQgB,OAAS,IACtDpC,EAASoB,GACLhB,KACFE,aAAaoB,QAAQxC,EAAkBuB,KAAKkB,UAAUP,IAExDnB,EAAYY,SAAU,EAE1B,IAOA,OAJKZ,EAAYY,SACfK,EAAUmB,QAAQlD,EAAcI,aAAc,MAGzC,WACL0B,IACAW,IACAI,IACAE,IACAC,IACAG,GACD,CArFA,CAsFF,GAAE,IAEI,CAAEvC,MAAAA,EAAOwC,WAAYxC,EAAMqC,OACpC,EASaI,EAAiB,WAqB5B,MAAO,CACLC,UApBgBC,GAAY,SAACZ,GAC7BZ,EAAUmB,QAAQlD,EAAcC,IAAK0C,EACtC,GAAE,IAmBDa,eAhBqBD,GAAY,SAACE,GAClC1B,EAAUmB,QAAQlD,EAAcE,OAAQ,CAAE0C,GAAIa,GAC/C,GAAE,IAeDC,UAZgBH,GAAY,WAC5BxB,EAAUmB,QAAQlD,EAAcG,MAAO,KACxC,GAAE,IAWDwD,WARiBJ,GAAY,SAAC3C,GAC9BmB,EAAUmB,QAAQlD,EAAcM,OAAQM,EACzC,GAAE,IAQL"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as t,Fragment as e}from"react/jsx-runtime";import{useState as a,useEffect as i}from"react";import{useCartStore as o,useCartActions as l}from"./cart.js";import{HydrationGuard as m}from"./hydration-helper.js";var n=function(n){var c=n.children,p=n.initialCartItems,s=void 0===p?[]:p;n.hydrateFromStorage,o().items;var d=l().updateCart,h=a(!1),u=r(h,2),f=u[0],v=u[1];return i((function(){!f&&s.length>0&&(d(s),v(!0))}),[f,s,d]),t(m,{serverFallback:t(e,{children:c}),hydrationDelay:100,children:c})};export{n as SsrCartProvider};
|
|
2
|
+
//# sourceMappingURL=cart.ssr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.ssr.js","sources":["../../src/mfe-shared/cart.ssr.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react'\r\nimport { ICartItem, useCartActions, useCartStore } from './cart'\r\nimport { HydrationGuard } from './hydration-helper'\r\n\r\n/**\r\n * Props for the SSR-compatible cart provider\r\n */\r\ninterface ISsrCartProviderProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n /** Should hydrate cart from browser storage after rendering */\r\n hydrateFromStorage?: boolean\r\n}\r\n\r\n/**\r\n * Cart provider component that supports SSR\r\n * \r\n * This component allows providing initial cart data during server-side rendering\r\n * and then hydrating from localStorage or other storage once client-side.\r\n */\r\nexport const SsrCartProvider: React.FC<ISsrCartProviderProps> = ({\r\n children,\r\n initialCartItems = [],\r\n hydrateFromStorage = true\r\n}) => {\r\n const { items } = useCartStore()\r\n const { updateCart } = useCartActions()\r\n const [isInitialized, setIsInitialized] = useState(false)\r\n\r\n // Initialize cart with provided items on first render\r\n useEffect(() => {\r\n if (!isInitialized && initialCartItems.length > 0) {\r\n updateCart(initialCartItems)\r\n setIsInitialized(true)\r\n }\r\n }, [isInitialized, initialCartItems, updateCart])\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={<>{children}</>}\r\n hydrationDelay={100}\r\n >\r\n {children}\r\n </HydrationGuard>\r\n )\r\n}\r\n\r\n/**\r\n * CartItemsComponent - SSR-aware cart items display component\r\n */\r\ninterface ICartItemsComponentProps {\r\n /** Function to render each cart item */\r\n renderItem: (item: ICartItem) => React.ReactNode\r\n /** Optional empty cart placeholder */\r\n emptyCart?: React.ReactNode\r\n /** Initial cart items for SSR */\r\n initialCartItems?: ICartItem[]\r\n}\r\n\r\n/**\r\n * SSR-compatible cart items component\r\n * \r\n * This component handles both server-side rendering with initial data\r\n * and client-side hydration from the cart store.\r\n */\r\nexport const CartItemsComponent: React.FC<ICartItemsComponentProps> = ({\r\n renderItem,\r\n emptyCart,\r\n initialCartItems = []\r\n}) => {\r\n const { items } = useCartStore()\r\n\r\n return (\r\n <HydrationGuard\r\n serverFallback={\r\n <>\r\n {initialCartItems.length === 0 && emptyCart}\r\n {initialCartItems.map(renderItem)}\r\n </>\r\n }\r\n >\r\n {items.length === 0 && emptyCart}\r\n {items.map(renderItem)}\r\n </HydrationGuard>\r\n )\r\n}\r\n"],"names":["SsrCartProvider","_ref","children","_ref$initialCartItems","initialCartItems","hydrateFromStorage","useCartStore","items","updateCart","useCartActions","_useState","useState","_useState2","_slicedToArray","isInitialized","setIsInitialized","useEffect","length","_jsx","HydrationGuard","serverFallback","_Fragment","hydrationDelay"],"mappings":"uSAsBaA,EAAmD,SAApCC,GAIvB,IAHHC,EAAQD,EAARC,SAAQC,EAAAF,EACRG,iBAAAA,OAAmB,IAAHD,EAAG,GAAEA,EAAAF,EACrBI,mBAEkBC,IAAVC,MACR,IAAQC,EAAeC,IAAfD,WACRE,EAA0CC,GAAS,GAAMC,EAAAC,EAAAH,EAAA,GAAlDI,EAAaF,EAAA,GAAEG,EAAgBH,EAAA,GAUtC,OAPAI,GAAU,YACHF,GAAiBV,EAAiBa,OAAS,IAC9CT,EAAWJ,GACXW,GAAiB,GAEpB,GAAE,CAACD,EAAeV,EAAkBI,IAGnCU,EAACC,EACC,CAAAC,eAAgBF,EAAGG,EAAA,CAAAnB,SAAAA,IACnBoB,eAAgB,aAEfpB,GAGP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sources":["../../src/mfe-shared/environment.ts"],"sourcesContent":["/**\r\n * Utility functions to check the environment\r\n */\r\n\r\n/**\r\n * Check if code is running in a browser environment\r\n * @returns boolean indicating if window is available\r\n */\r\nexport const isBrowser = (): boolean => {\r\n return typeof window !== 'undefined' && !!window\r\n}\r\n\r\n/**\r\n * Safe access to window object for browser environments\r\n * @returns window object or undefined\r\n */\r\nexport const getBrowserGlobal = (): Window | undefined => {\r\n return isBrowser() ? window : undefined\r\n}\r\n\r\n/**\r\n * Safe access to globalThis object with browser fallback\r\n * @returns globalThis object\r\n */\r\nexport const getGlobal = (): any => {\r\n return typeof globalThis !== 'undefined' ? globalThis : getBrowserGlobal()\r\n}\r\n"],"names":["isBrowser","window"],"mappings":"IAQaA,EAAY,WACvB,MAAyB,oBAAXC,UAA4BA,MAC5C"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{slicedToArray as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as e,Fragment as n}from"react/jsx-runtime";import{useState as i,useEffect as t}from"react";import{isBrowser as o}from"./environment.js";var l;!function(r){r.SERVER="server",r.HYDRATING="hydrating",r.HYDRATED="hydrated"}(l||(l={}));var a=function(a){var u=a.children,c=a.serverFallback,R=a.hydrationFallback,m=a.hydrationDelay,d=void 0===m?0:m,f=o()?l.HYDRATING:l.SERVER,D=i(f),E=r(D,2),T=E[0],s=E[1];return t((function(){if(T===l.SERVER&&s(l.HYDRATING),T===l.HYDRATING){var r=setTimeout((function(){s(l.HYDRATED)}),d);return function(){return clearTimeout(r)}}}),[T,d]),T===l.SERVER?e(n,{children:null!=c?c:u}):T===l.HYDRATING?e(n,{children:null!=R?R:u}):e(n,{children:u})};export{a as HydrationGuard,l as HydrationState};
|
|
2
|
+
//# sourceMappingURL=hydration-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-helper.js","sources":["../../src/mfe-shared/hydration-helper.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport { isBrowser } from './environment'\r\n\r\n/**\r\n * Hydration state for components\r\n */\r\nexport enum HydrationState {\r\n /** Component is rendering on the server */\r\n SERVER = 'server',\r\n /** Component is in the process of hydrating on the client */\r\n HYDRATING = 'hydrating',\r\n /** Component is fully hydrated on the client */\r\n HYDRATED = 'hydrated'\r\n}\r\n\r\n/**\r\n * Props for the HydrationGuard component\r\n */\r\nexport interface HydrationGuardProps {\r\n /** Content to render */\r\n children: React.ReactNode\r\n /** Optional fallback content to show during server rendering */\r\n serverFallback?: React.ReactNode\r\n /** Optional fallback content to show during hydration */\r\n hydrationFallback?: React.ReactNode\r\n /**\r\n * Optional delay in milliseconds before considering the component hydrated\r\n * This can help with \"flash of content\" issues\r\n */\r\n hydrationDelay?: number\r\n}\r\n\r\n/**\r\n * HydrationGuard - Component to handle SSR hydration\r\n * \r\n * This component helps manage the transition between server-rendered content\r\n * and client-side hydration, allowing different content to be shown during\r\n * different stages of the hydration process.\r\n */\r\nexport const HydrationGuard: React.FC<HydrationGuardProps> = ({\r\n children,\r\n serverFallback,\r\n hydrationFallback,\r\n hydrationDelay = 0\r\n}) => {\r\n // Determine initial hydration state\r\n const initialState = !isBrowser() \r\n ? HydrationState.SERVER \r\n : HydrationState.HYDRATING\r\n \r\n const [hydrationState, setHydrationState] = useState<HydrationState>(initialState)\r\n\r\n useEffect(() => {\r\n // We're now client-side, so at minimum we're hydrating\r\n if (hydrationState === HydrationState.SERVER) {\r\n setHydrationState(HydrationState.HYDRATING)\r\n }\r\n\r\n // If we're hydrating, set a timer to transition to fully hydrated\r\n if (hydrationState === HydrationState.HYDRATING) {\r\n const timer = setTimeout(() => {\r\n setHydrationState(HydrationState.HYDRATED)\r\n }, hydrationDelay)\r\n \r\n return () => clearTimeout(timer)\r\n }\r\n }, [hydrationState, hydrationDelay])\r\n\r\n // Render appropriate content based on hydration state\r\n if (hydrationState === HydrationState.SERVER) {\r\n return <>{serverFallback ?? children}</>\r\n }\r\n\r\n if (hydrationState === HydrationState.HYDRATING) {\r\n return <>{hydrationFallback ?? children}</>\r\n }\r\n\r\n return <>{children}</>\r\n}\r\n\r\n/**\r\n * Hook to get the current hydration state\r\n * \r\n * Use this hook to conditionally run code based on whether the component\r\n * is being rendered on the server or has been hydrated on the client.\r\n * \r\n * @param hydrationDelay Optional delay before considering the component hydrated\r\n * @returns Current hydration state\r\n */\r\nexport const useHydration = (hydrationDelay = 0): HydrationState => {\r\n const initialState = !isBrowser() \r\n ? HydrationState.SERVER \r\n : HydrationState.HYDRATING\r\n \r\n const [hydrationState, setHydrationState] = useState<HydrationState>(initialState)\r\n\r\n useEffect(() => {\r\n // We're now client-side, so at minimum we're hydrating\r\n if (hydrationState === HydrationState.SERVER) {\r\n setHydrationState(HydrationState.HYDRATING)\r\n }\r\n\r\n // If we're hydrating, set a timer to transition to fully hydrated\r\n if (hydrationState === HydrationState.HYDRATING) {\r\n const timer = setTimeout(() => {\r\n setHydrationState(HydrationState.HYDRATED)\r\n }, hydrationDelay)\r\n \r\n return () => clearTimeout(timer)\r\n }\r\n }, [hydrationState, hydrationDelay])\r\n\r\n return hydrationState\r\n}\r\n"],"names":["HydrationState","HydrationGuard","_ref","children","serverFallback","hydrationFallback","_ref$hydrationDelay","hydrationDelay","initialState","isBrowser","HYDRATING","SERVER","_useState","useState","_useState2","_slicedToArray","hydrationState","setHydrationState","useEffect","timer","setTimeout","HYDRATED","clearTimeout","_jsx","_Fragment"],"mappings":"gOAMYA,GAAZ,SAAYA,GAEVA,EAAA,OAAA,SAEAA,EAAA,UAAA,YAEAA,EAAA,SAAA,UACD,CAPD,CAAYA,IAAAA,EAOX,CAAA,QA0BYC,EAAgD,SAAlCC,GAKtB,IAJHC,EAAQD,EAARC,SACAC,EAAcF,EAAdE,eACAC,EAAiBH,EAAjBG,kBAAiBC,EAAAJ,EACjBK,eAAAA,OAAiB,IAAHD,EAAG,EAACA,EAGZE,EAAgBC,IAElBT,EAAeU,UADfV,EAAeW,OAGnBC,EAA4CC,EAAyBL,GAAaM,EAAAC,EAAAH,EAAA,GAA3EI,EAAcF,EAAA,GAAEG,EAAiBH,EAAA,GAmBxC,OAjBAI,GAAU,WAOR,GALIF,IAAmBhB,EAAeW,QACpCM,EAAkBjB,EAAeU,WAI/BM,IAAmBhB,EAAeU,UAAW,CAC/C,IAAMS,EAAQC,YAAW,WACvBH,EAAkBjB,EAAeqB,SAClC,GAAEd,GAEH,OAAO,WAAA,OAAMe,aAAaH,EAAM,CACjC,CACH,GAAG,CAACH,EAAgBT,IAGhBS,IAAmBhB,EAAeW,OAC7BY,EAAGC,EAAA,CAAArB,SAAAC,QAAAA,EAAkBD,IAG1Ba,IAAmBhB,EAAeU,UAC7Ba,EAAGC,EAAA,CAAArB,SAAAE,QAAAA,EAAqBF,IAG1BoB,EAAAC,EAAA,CAAArB,SAAGA,GACZ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export{mfeBridge}from"./mfe-bridge.js";export{AuthProvider,useAuth}from"./auth.js";export{AUTH_CHANNELS}from"./auth.types.js";export{SsrAuthProvider}from"./auth.ssr.js";export{CART_CHANNELS,useCartActions,useCartStore}from"./cart.js";export{SsrCartProvider}from"./cart.ssr.js";export{MfeLink,MfeNavigateReactProvider,NAVIGATION_CHANNELS,useMfeNavigate}from"./navigation.js";export{isBrowser}from"./environment.js";export{HydrationGuard}from"./hydration-helper.js";
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createClass as e,createForOfIteratorHelper as n,classCallCheck as i,defineProperty as r}from"../_virtual/_rollupPluginBabelHelpers.js";import{isBrowser as a}from"./environment.js";var t=new(function(){return e((function e(){i(this,e),r(this,"middlewares",[])}),[{key:"subscribe",value:function(e,n){if(!a())return function(){};var i=function(i){var r,a=i;(null===(r=a.detail)||void 0===r?void 0:r.__channel)===e&&n(a.detail.payload)};return window.addEventListener(e,i),function(){a()&&window.removeEventListener(e,i)}}},{key:"publish",value:function(e,i){if(a()){var r,t=n(this.middlewares);try{for(t.s();!(r=t.n()).done;){if(!1===(0,r.value)(e,i))return}}catch(e){t.e(e)}finally{t.f()}var l=new CustomEvent(e,{detail:{__channel:e,payload:i}});window.dispatchEvent(l)}}},{key:"use",value:function(e){this.middlewares.push(e)}},{key:"clearMiddlewares",value:function(){this.middlewares=[]}}])}());export{t as mfeBridge};
|
|
2
|
+
//# sourceMappingURL=mfe-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfe-bridge.js","sources":["../../src/mfe-shared/mfe-bridge.tsx"],"sourcesContent":["import { isBrowser } from './environment'\r\n\r\n/**\r\n * Callback function type for event subscribers\r\n * @template T Type of payload data\r\n */\r\ntype Callback<T = any> = (payload: T) => void\r\n\r\n/**\r\n * Middleware function type for intercepting events\r\n * @returns boolean|void Return false to cancel event propagation\r\n */\r\ntype Middleware = (channel: string, payload: any) => boolean | void\r\n\r\n/**\r\n * MfeBridge - Event-based communication system for micro-frontends\r\n * \r\n * This class provides a way for different micro-frontends to communicate\r\n * with each other via a publish/subscribe pattern using CustomEvents.\r\n * Includes SSR compatibility checks.\r\n */\r\nclass MfeBridge {\r\n private middlewares: Middleware[] = []\r\n\r\n /**\r\n * Subscribe to events on a specific channel\r\n * @template T Type of payload data\r\n * @param channel The channel to subscribe to\r\n * @param callback Function to call when an event occurs on this channel\r\n * @returns Unsubscribe function to remove the event listener\r\n */\r\n subscribe<T = any>(channel: string, callback: Callback<T>) {\r\n // No-op function for SSR environment\r\n const noop = () => {}\r\n \r\n // If not in browser environment, return no-op\r\n if (!isBrowser()) {\r\n return noop\r\n }\r\n\r\n const handler = (e: Event) => {\r\n const customEvent = e as CustomEvent\r\n if (customEvent.detail?.__channel === channel) {\r\n callback(customEvent.detail.payload)\r\n }\r\n }\r\n\r\n window.addEventListener(channel, handler)\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n if (isBrowser()) {\r\n window.removeEventListener(channel, handler)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Publish an event to a specific channel\r\n * @template T Type of payload data\r\n * @param channel The channel to publish to\r\n * @param payload Data to send with the event\r\n */\r\n publish<T = any>(channel: string, payload: T) {\r\n // Skip in SSR environment\r\n if (!isBrowser()) {\r\n return\r\n }\r\n \r\n // Run through middleware stack\r\n for (const mw of this.middlewares) {\r\n const result = mw(channel, payload)\r\n if (result === false) return // middleware can cancel\r\n }\r\n\r\n const event = new CustomEvent(channel, { detail: { __channel: channel, payload } })\r\n window.dispatchEvent(event)\r\n }\r\n\r\n /**\r\n * Add middleware to intercept events before they're published\r\n * @param middleware Function that can inspect or modify events\r\n */\r\n use(middleware: Middleware) {\r\n this.middlewares.push(middleware)\r\n }\r\n\r\n /**\r\n * Remove all middleware\r\n */\r\n clearMiddlewares() {\r\n this.middlewares = []\r\n }\r\n}\r\n\r\n// Export a singleton instance to be used throughout the application\r\nexport const mfeBridge = new MfeBridge()\r\n"],"names":["mfeBridge","_createClass","MfeBridge","_classCallCheck","_defineProperty","key","value","channel","callback","isBrowser","handler","e","_customEvent$detail","customEvent","detail","__channel","payload","window","addEventListener","removeEventListener","_step","_iterator","_createForOfIteratorHelper","this","middlewares","s","n","done","mw","err","f","event","CustomEvent","dispatchEvent","middleware","push"],"mappings":"2LAcA,IAkFaA,EAAY,IA3EV,WACyB,OAAAC,GADzB,SAAAC,IAAAC,OAAAD,GAAAE,qBACuB,GAAE,GAAA,CAAA,CAAAC,IAAA,YAAAC,MAStC,SAAmBC,EAAiBC,GAKlC,IAAKC,IACH,OAJW,WAAQ,EAOrB,IAAMC,EAAU,SAACC,GAAY,IAAAC,EACrBC,EAAcF,GACE,QAAlBC,EAAAC,EAAYC,cAAM,IAAAF,OAAA,EAAlBA,EAAoBG,aAAcR,GACpCC,EAASK,EAAYC,OAAOE,QAE/B,EAKD,OAHAC,OAAOC,iBAAiBX,EAASG,GAG1B,WACDD,KACFQ,OAAOE,oBAAoBZ,EAASG,EAEvC,CACH,GAEA,CAAAL,IAAA,UAAAC,MAMA,SAAiBC,EAAiBS,GAEhC,GAAKP,IAAL,CAIA,IACiCW,EADjCC,EAAAC,EACiBC,KAAKC,aAAW,IAAjC,IAAAH,EAAAI,MAAAL,EAAAC,EAAAK,KAAAC,MAAmC,CAEjC,IAAe,KADAC,EADJR,EAAAd,OACOC,EAASS,GACL,MACvB,CAAA,CAAA,MAAAa,GAAAR,EAAAV,EAAAkB,EAAA,CAAA,QAAAR,EAAAS,GAAA,CAED,IAAMC,EAAQ,IAAIC,YAAYzB,EAAS,CAAEO,OAAQ,CAAEC,UAAWR,EAASS,QAAAA,KACvEC,OAAOgB,cAAcF,EATpB,CAUH,GAEA,CAAA1B,IAAA,MAAAC,MAIA,SAAI4B,GACFX,KAAKC,YAAYW,KAAKD,EACxB,GAEA,CAAA7B,IAAA,mBAAAC,MAGA,WACEiB,KAAKC,YAAc,EACrB,IAAC,CAvEY"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{objectWithoutProperties as r,objectSpread2 as n}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useEffect as i}from"react";import{mfeBridge as a}from"./mfe-bridge.js";import{isBrowser as o}from"./environment.js";var f=["internal","primaryHref","secondaryHref","onClick"],u={NAVIGATE:"mfe:navigation:navigate"},c=function(){return{navigate:function(r){a.publish(u.NAVIGATE,r)}}},l=function(t){var i=t.internal,a=t.primaryHref,o=t.secondaryHref,u=t.onClick,l=r(t,f),m=c().navigate;return e("a",n(n({},l),{},{href:a,onClick:function(r){if(u&&u(r),!r.defaultPrevented)return i&&o?(r.preventDefault(),void m({primaryHref:a,secondaryHref:o,internal:i})):void 0}}))},m=function(r){var n=r.navigate;return i((function(){var r=a.subscribe(u.NAVIGATE,(function(r){var e=r.primaryHref,t=r.secondaryHref,i=r.options;if(e){var a=t||e||"/";"_blank"!==(null==i?void 0:i.target)?n(a,i):o()&&window.open("".concat(a),"_blank")}}));return function(){return r()}}),[n]),e(t,{})};export{l as MfeLink,m as MfeNavigateReactProvider,u as NAVIGATION_CHANNELS,c as useMfeNavigate};
|
|
2
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sources":["../../src/mfe-shared/navigation.tsx"],"sourcesContent":["import { useEffect, type AnchorHTMLAttributes, type FC } from 'react'\r\nimport { mfeBridge } from './mfe-bridge'\r\nimport { isBrowser } from './environment'\r\n\r\n// Define channels for navigation events\r\nexport const NAVIGATION_CHANNELS = {\r\n NAVIGATE: 'mfe:navigation:navigate'\r\n}\r\n\r\nexport type AppSite = 'client' | 'home' | 'music'\r\n\r\nexport type IMfeNavigateHref = {\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport interface IMfeNavigate {\r\n primaryHref: string\r\n secondaryHref?: string\r\n internal?: boolean\r\n site?: AppSite\r\n options?: any\r\n target?: '_self' | '_blank'\r\n}\r\n\r\nexport /**\r\n * Hook for navigation between micro-frontends\r\n * @returns Navigation utilities\r\n */\r\nconst useMfeNavigate = () => {\r\n const navigate = (params: IMfeNavigate) => {\r\n // Use mfeBridge consistently instead of direct globalThis.dispatchEvent\r\n mfeBridge.publish(NAVIGATION_CHANNELS.NAVIGATE, params)\r\n }\r\n return { navigate }\r\n}\r\n\r\nexport interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\r\n internal?: boolean\r\n primaryHref: string\r\n secondaryHref?: string\r\n}\r\n\r\nexport const MfeLink: FC<IMfeLinkProps> = (props) => {\r\n const { internal, primaryHref, secondaryHref, onClick, ...rest } = props\r\n const { navigate } = useMfeNavigate()\r\n\r\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (onClick) onClick(e)\r\n if (e.defaultPrevented) return\r\n if (internal && secondaryHref) {\r\n e.preventDefault()\r\n navigate({ primaryHref, secondaryHref, internal })\r\n return\r\n }\r\n // If not internal or no secondaryHref, let the anchor tag handle it\r\n }\r\n\r\n return <a {...rest} href={primaryHref} onClick={handleClick} />\r\n}\r\n\r\n// Define types to avoid direct imports\r\nexport type NavigateFunction<O = any> = (path: string, options?: O) => void\r\n\r\nexport interface IMfeNavigateReactProviderProps {\r\n navigate: NavigateFunction\r\n}\r\n\r\nexport const MfeNavigateReactProvider: FC<IMfeNavigateReactProviderProps> = ({ navigate }) => {\r\n useEffect(() => {\r\n const unsubscribe = mfeBridge.subscribe(NAVIGATION_CHANNELS.NAVIGATE, (payload: IMfeNavigate) => {\r\n const { primaryHref, secondaryHref, options } = payload\r\n if (!primaryHref) return\r\n // Navigate to secondaryHref if available, otherwise fallback to primaryHref\r\n const url = secondaryHref || primaryHref || '/'\r\n if (options?.target === '_blank') {\r\n // Only open in new window if in browser environment\r\n if (isBrowser()) {\r\n window.open(`${url}`, '_blank')\r\n }\r\n return\r\n }\r\n navigate(url, options)\r\n })\r\n return () => unsubscribe() // Unsubscribe from the event\r\n }, [navigate])\r\n return <></>\r\n}\r\n"],"names":["NAVIGATION_CHANNELS","NAVIGATE","useMfeNavigate","navigate","params","mfeBridge","publish","MfeLink","props","internal","primaryHref","secondaryHref","onClick","rest","_objectWithoutProperties","_excluded","_jsx","_objectSpread","href","e","defaultPrevented","preventDefault","MfeNavigateReactProvider","_ref","useEffect","unsubscribe","subscribe","payload","options","url","target","isBrowser","window","open","concat"],"mappings":"kVAKaA,EAAsB,CACjCC,SAAU,2BAuBNC,EAAiB,WAKrB,MAAO,CAAEC,SAJQ,SAACC,GAEhBC,EAAUC,QAAQN,EAAoBC,SAAUG,EACjD,EAEH,EAQaG,EAA6B,SAACC,GACzC,IAAQC,EAA2DD,EAA3DC,SAAUC,EAAiDF,EAAjDE,YAAaC,EAAoCH,EAApCG,cAAeC,EAAqBJ,EAArBI,QAAYC,EAAIC,EAAKN,EAAKO,GAChEZ,EAAaD,IAAbC,SAaR,OAAOa,EAAA,IAAAC,EAAAA,KAAOJ,GAAI,GAAA,CAAEK,KAAMR,EAAaE,QAXnB,SAACO,GAEnB,GADIP,GAASA,EAAQO,IACjBA,EAAEC,iBACN,OAAIX,GAAYE,GACdQ,EAAEE,sBACFlB,EAAS,CAAEO,YAAAA,EAAaC,cAAAA,EAAeF,SAAAA,UAFzC,CAMD,IAGH,EASaa,EAA+D,SAAvCC,GAAwD,IAAdpB,EAAQoB,EAARpB,SAkB7E,OAjBAqB,GAAU,WACR,IAAMC,EAAcpB,EAAUqB,UAAU1B,EAAoBC,UAAU,SAAC0B,GACrE,IAAQjB,EAAwCiB,EAAxCjB,YAAaC,EAA2BgB,EAA3BhB,cAAeiB,EAAYD,EAAZC,QACpC,GAAKlB,EAAL,CAEA,IAAMmB,EAAMlB,GAAiBD,GAAe,IACpB,YAApBkB,aAAO,EAAPA,EAASE,QAOb3B,EAAS0B,EAAKD,GALRG,KACFC,OAAOC,KAAIC,GAAAA,OAAIL,GAAO,SANR,CAWpB,IACA,OAAO,WAAA,OAAMJ,GAAa,CAC5B,GAAG,CAACtB,IACGa,OACT"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { AnchorHTMLAttributes, FC } from 'react';
|
|
1
|
+
import type { AnchorHTMLAttributes, FC } from 'react';
|
|
2
2
|
import type { MfeNavigate } from './types';
|
|
3
3
|
export declare const useMfeNavigate: () => {
|
|
4
4
|
navigate: (params: MfeNavigate) => void;
|
|
5
5
|
};
|
|
6
6
|
export interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
internal?: boolean;
|
|
8
|
+
primaryHref: string;
|
|
9
|
+
secondaryHref?: string;
|
|
9
10
|
}
|
|
10
11
|
export declare const MfeLink: FC<IMfeLinkProps>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type AppSite = 'client' | 'home' | 'music';
|
|
2
|
+
export type IMfeNavigateHref = {
|
|
3
|
+
primaryHref: string;
|
|
4
|
+
secondaryHref?: string;
|
|
5
|
+
};
|
|
6
|
+
export interface MfeNavigate {
|
|
7
|
+
primaryHref: string;
|
|
8
|
+
secondaryHref?: string;
|
|
9
|
+
internal?: boolean;
|
|
10
|
+
site?: AppSite;
|
|
11
|
+
options?: any;
|
|
12
|
+
target?: '_self' | '_blank';
|
|
13
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AuthState, User } from './auth.types';
|
|
3
|
+
interface ILoginParams {
|
|
4
|
+
username: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
interface ILoginResponse {
|
|
8
|
+
isAuthenticated: boolean;
|
|
9
|
+
user?: User;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface IAuthProviderProps {
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
onLogin?: (params: ILoginParams) => Promise<ILoginResponse | void>;
|
|
15
|
+
onLogout?: () => Promise<boolean | void>;
|
|
16
|
+
initialState?: AuthState;
|
|
17
|
+
authData?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
displayName?: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
avatar?: string;
|
|
22
|
+
roles?: string[];
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
};
|
|
25
|
+
onAuthChange?: (callback: (newState: AuthState) => void) => () => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* AuthProvider - Component for Host application
|
|
29
|
+
*
|
|
30
|
+
* Manages authentication state and broadcasts events to MFEs.
|
|
31
|
+
* Place this component anywhere in your application, no need to wrap other components.
|
|
32
|
+
*
|
|
33
|
+
* Host can customize login/logout behavior by providing custom handlers.
|
|
34
|
+
*/
|
|
35
|
+
export declare const AuthProvider: React.FC<IAuthProviderProps>;
|
|
36
|
+
export declare function useAuth(): {
|
|
37
|
+
login: (username: string, password: string) => void;
|
|
38
|
+
logout: () => void;
|
|
39
|
+
isAuthenticated: boolean;
|
|
40
|
+
isLoading: boolean;
|
|
41
|
+
user: User | null;
|
|
42
|
+
error: string | null;
|
|
43
|
+
serverRendered?: boolean | undefined;
|
|
44
|
+
};
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AuthState, User } from './auth.types';
|
|
3
|
+
import { type IAuthProviderProps } from './auth';
|
|
4
|
+
/**
|
|
5
|
+
* Props for the SSR-compatible auth provider
|
|
6
|
+
*/
|
|
7
|
+
interface ISsrAuthProviderProps {
|
|
8
|
+
/** Content to render */
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
/** Initial auth state for SSR */
|
|
11
|
+
initialAuthState?: AuthState;
|
|
12
|
+
/** User data for initial state */
|
|
13
|
+
userData?: User;
|
|
14
|
+
/** Custom auth data to be passed to AuthProvider */
|
|
15
|
+
authData?: {
|
|
16
|
+
id?: string;
|
|
17
|
+
displayName?: string;
|
|
18
|
+
email?: string;
|
|
19
|
+
avatar?: string;
|
|
20
|
+
roles?: string[];
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
};
|
|
23
|
+
/** Custom login handler */
|
|
24
|
+
onLogin?: IAuthProviderProps['onLogin'];
|
|
25
|
+
/** Custom logout handler */
|
|
26
|
+
onLogout?: IAuthProviderProps['onLogout'];
|
|
27
|
+
/** Auth state change subscription */
|
|
28
|
+
onAuthChange?: IAuthProviderProps['onAuthChange'];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Auth provider component that supports SSR
|
|
32
|
+
*
|
|
33
|
+
* This component allows providing initial auth data during server-side rendering
|
|
34
|
+
* and then hydrating from API or other sources once client-side.
|
|
35
|
+
*/
|
|
36
|
+
export declare const SsrAuthProvider: React.FC<ISsrAuthProviderProps>;
|
|
37
|
+
/**
|
|
38
|
+
* Props for the SSR-compatible authenticated content component
|
|
39
|
+
*/
|
|
40
|
+
interface IAuthenticatedContentProps {
|
|
41
|
+
/** Content to show when authenticated */
|
|
42
|
+
children: React.ReactNode;
|
|
43
|
+
/** Content to show when not authenticated */
|
|
44
|
+
fallback?: React.ReactNode;
|
|
45
|
+
/** Initial authentication state for SSR */
|
|
46
|
+
initiallyAuthenticated?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Component that conditionally renders content based on authentication state
|
|
50
|
+
* with SSR support
|
|
51
|
+
*/
|
|
52
|
+
export declare const AuthenticatedContent: React.FC<IAuthenticatedContentProps>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth.types.ts - Type definitions for Authentication System
|
|
3
|
+
*
|
|
4
|
+
* This file defines the data structures and communication channels
|
|
5
|
+
* for the micro-frontend authentication system.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* User data structure
|
|
9
|
+
*/
|
|
10
|
+
export type User = {
|
|
11
|
+
/** Unique identifier for the user */
|
|
12
|
+
id: string;
|
|
13
|
+
/** User's display name */
|
|
14
|
+
displayName: string;
|
|
15
|
+
/** User's email address */
|
|
16
|
+
email: string;
|
|
17
|
+
/** Optional URL to user's avatar image */
|
|
18
|
+
avatar?: string;
|
|
19
|
+
/** List of roles/permissions assigned to the user */
|
|
20
|
+
roles: string[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Authentication state structure
|
|
24
|
+
*/
|
|
25
|
+
export type AuthState = {
|
|
26
|
+
/** Whether the user is currently authenticated */
|
|
27
|
+
isAuthenticated: boolean;
|
|
28
|
+
/** Whether an authentication operation is in progress */
|
|
29
|
+
isLoading: boolean;
|
|
30
|
+
/** The authenticated user, or null if not authenticated */
|
|
31
|
+
user: User | null;
|
|
32
|
+
/** Error message if authentication failed, or null */
|
|
33
|
+
error: string | null;
|
|
34
|
+
/** Whether the auth state was rendered on the server */
|
|
35
|
+
serverRendered?: boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Communication channels between auth provider and consumers
|
|
39
|
+
*/
|
|
40
|
+
export declare const AUTH_CHANNELS: {
|
|
41
|
+
/** Provider → Consumer: Notify when auth state changes */
|
|
42
|
+
STATE_CHANGE: string;
|
|
43
|
+
/** Consumer → Provider: Request the current auth state */
|
|
44
|
+
REQUEST_STATE: string;
|
|
45
|
+
/** Consumer → Provider: Request to log in */
|
|
46
|
+
LOGIN: string;
|
|
47
|
+
/** Consumer → Provider: Request to log out */
|
|
48
|
+
LOGOUT: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Default authentication state - unauthenticated, not loading, no user, no error
|
|
52
|
+
*/
|
|
53
|
+
export declare const INITIAL_AUTH_STATE: AuthState;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cart.tsx - Shared shopping cart system for micro-frontends
|
|
3
|
+
*
|
|
4
|
+
* This module provides hooks for managing a shared shopping cart across
|
|
5
|
+
* multiple micro-frontends. The cart state is synchronized using the
|
|
6
|
+
* mfeBridge communication system and persisted in localStorage.
|
|
7
|
+
*/
|
|
8
|
+
/** Communication channels for cart operations */
|
|
9
|
+
export declare const CART_CHANNELS: {
|
|
10
|
+
/** Add an item to the cart */
|
|
11
|
+
ADD: string;
|
|
12
|
+
/** Remove an item from the cart */
|
|
13
|
+
REMOVE: string;
|
|
14
|
+
/** Clear all items from the cart */
|
|
15
|
+
CLEAR: string;
|
|
16
|
+
/** Request initial cart data (when a new MFE loads) */
|
|
17
|
+
INIT_REQUEST: string;
|
|
18
|
+
/** Response with cart data (to initialize a new MFE) */
|
|
19
|
+
INIT_RESPONSE: string;
|
|
20
|
+
/** Update the entire cart at once */
|
|
21
|
+
UPDATE: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Shopping cart item structure
|
|
25
|
+
*/
|
|
26
|
+
export interface ICartItem {
|
|
27
|
+
/** Unique identifier for the item */
|
|
28
|
+
id: number;
|
|
29
|
+
/** Display name of the item */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Quantity of this item in the cart */
|
|
32
|
+
quantity: number;
|
|
33
|
+
/** Price per unit of the item */
|
|
34
|
+
price: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Hook to manage cart state across microFE
|
|
38
|
+
* This hook will:
|
|
39
|
+
* - Initialize cart from localStorage
|
|
40
|
+
* - Listen for cart events (add, remove, clear, update)
|
|
41
|
+
* - Provide current cart state
|
|
42
|
+
*/
|
|
43
|
+
export declare const useCartStore: () => {
|
|
44
|
+
items: ICartItem[];
|
|
45
|
+
totalItems: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Hook to provide cart actions
|
|
49
|
+
* This hook will:
|
|
50
|
+
* - Only perform actions, not manage state
|
|
51
|
+
* - Use mfeEventBridge to communicate with other microFEs
|
|
52
|
+
* - Provide add, remove, clear, and update actions
|
|
53
|
+
*/
|
|
54
|
+
export declare const useCartActions: () => {
|
|
55
|
+
addToCart: (item: ICartItem) => void;
|
|
56
|
+
removeFromCart: (itemId: number) => void;
|
|
57
|
+
clearCart: () => void;
|
|
58
|
+
updateCart: (items: ICartItem[]) => void;
|
|
59
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ICartItem } from './cart';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the SSR-compatible cart provider
|
|
5
|
+
*/
|
|
6
|
+
interface ISsrCartProviderProps {
|
|
7
|
+
/** Content to render */
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Initial cart items for SSR */
|
|
10
|
+
initialCartItems?: ICartItem[];
|
|
11
|
+
/** Should hydrate cart from browser storage after rendering */
|
|
12
|
+
hydrateFromStorage?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Cart provider component that supports SSR
|
|
16
|
+
*
|
|
17
|
+
* This component allows providing initial cart data during server-side rendering
|
|
18
|
+
* and then hydrating from localStorage or other storage once client-side.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SsrCartProvider: React.FC<ISsrCartProviderProps>;
|
|
21
|
+
/**
|
|
22
|
+
* CartItemsComponent - SSR-aware cart items display component
|
|
23
|
+
*/
|
|
24
|
+
interface ICartItemsComponentProps {
|
|
25
|
+
/** Function to render each cart item */
|
|
26
|
+
renderItem: (item: ICartItem) => React.ReactNode;
|
|
27
|
+
/** Optional empty cart placeholder */
|
|
28
|
+
emptyCart?: React.ReactNode;
|
|
29
|
+
/** Initial cart items for SSR */
|
|
30
|
+
initialCartItems?: ICartItem[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* SSR-compatible cart items component
|
|
34
|
+
*
|
|
35
|
+
* This component handles both server-side rendering with initial data
|
|
36
|
+
* and client-side hydration from the cart store.
|
|
37
|
+
*/
|
|
38
|
+
export declare const CartItemsComponent: React.FC<ICartItemsComponentProps>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions to check the environment
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if code is running in a browser environment
|
|
6
|
+
* @returns boolean indicating if window is available
|
|
7
|
+
*/
|
|
8
|
+
export declare const isBrowser: () => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Safe access to window object for browser environments
|
|
11
|
+
* @returns window object or undefined
|
|
12
|
+
*/
|
|
13
|
+
export declare const getBrowserGlobal: () => Window | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Safe access to globalThis object with browser fallback
|
|
16
|
+
* @returns globalThis object
|
|
17
|
+
*/
|
|
18
|
+
export declare const getGlobal: () => any;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hydration state for components
|
|
4
|
+
*/
|
|
5
|
+
export declare enum HydrationState {
|
|
6
|
+
/** Component is rendering on the server */
|
|
7
|
+
SERVER = "server",
|
|
8
|
+
/** Component is in the process of hydrating on the client */
|
|
9
|
+
HYDRATING = "hydrating",
|
|
10
|
+
/** Component is fully hydrated on the client */
|
|
11
|
+
HYDRATED = "hydrated"
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for the HydrationGuard component
|
|
15
|
+
*/
|
|
16
|
+
export interface HydrationGuardProps {
|
|
17
|
+
/** Content to render */
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
/** Optional fallback content to show during server rendering */
|
|
20
|
+
serverFallback?: React.ReactNode;
|
|
21
|
+
/** Optional fallback content to show during hydration */
|
|
22
|
+
hydrationFallback?: React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Optional delay in milliseconds before considering the component hydrated
|
|
25
|
+
* This can help with "flash of content" issues
|
|
26
|
+
*/
|
|
27
|
+
hydrationDelay?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* HydrationGuard - Component to handle SSR hydration
|
|
31
|
+
*
|
|
32
|
+
* This component helps manage the transition between server-rendered content
|
|
33
|
+
* and client-side hydration, allowing different content to be shown during
|
|
34
|
+
* different stages of the hydration process.
|
|
35
|
+
*/
|
|
36
|
+
export declare const HydrationGuard: React.FC<HydrationGuardProps>;
|
|
37
|
+
/**
|
|
38
|
+
* Hook to get the current hydration state
|
|
39
|
+
*
|
|
40
|
+
* Use this hook to conditionally run code based on whether the component
|
|
41
|
+
* is being rendered on the server or has been hydrated on the client.
|
|
42
|
+
*
|
|
43
|
+
* @param hydrationDelay Optional delay before considering the component hydrated
|
|
44
|
+
* @returns Current hydration state
|
|
45
|
+
*/
|
|
46
|
+
export declare const useHydration: (hydrationDelay?: number) => HydrationState;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mfe-shared - Core library for micro-frontend communication and shared state
|
|
3
|
+
*
|
|
4
|
+
* This module provides a standardized way for micro-frontends to communicate and share state.
|
|
5
|
+
* Only the public API is exported here, internal implementation details are hidden.
|
|
6
|
+
*/
|
|
7
|
+
export { mfeBridge } from './mfe-bridge';
|
|
8
|
+
export { AuthProvider, type IAuthProviderProps } from './auth';
|
|
9
|
+
export { useAuth } from './auth';
|
|
10
|
+
export { type AuthState, type User } from './auth.types';
|
|
11
|
+
export { AUTH_CHANNELS } from './auth.types';
|
|
12
|
+
export { SsrAuthProvider } from './auth.ssr';
|
|
13
|
+
export { useCartStore, useCartActions } from './cart';
|
|
14
|
+
export type { ICartItem } from './cart';
|
|
15
|
+
export { CART_CHANNELS } from './cart';
|
|
16
|
+
export { SsrCartProvider } from './cart.ssr';
|
|
17
|
+
export { useMfeNavigate, MfeLink, MfeNavigateReactProvider } from './navigation';
|
|
18
|
+
export type { IMfeNavigate, IMfeLinkProps } from './navigation';
|
|
19
|
+
export { NAVIGATION_CHANNELS } from './navigation';
|
|
20
|
+
export { isBrowser } from './environment';
|
|
21
|
+
export { HydrationGuard } from './hydration-helper';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Callback function type for event subscribers
|
|
3
|
+
* @template T Type of payload data
|
|
4
|
+
*/
|
|
5
|
+
type Callback<T = any> = (payload: T) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Middleware function type for intercepting events
|
|
8
|
+
* @returns boolean|void Return false to cancel event propagation
|
|
9
|
+
*/
|
|
10
|
+
type Middleware = (channel: string, payload: any) => boolean | void;
|
|
11
|
+
/**
|
|
12
|
+
* MfeBridge - Event-based communication system for micro-frontends
|
|
13
|
+
*
|
|
14
|
+
* This class provides a way for different micro-frontends to communicate
|
|
15
|
+
* with each other via a publish/subscribe pattern using CustomEvents.
|
|
16
|
+
* Includes SSR compatibility checks.
|
|
17
|
+
*/
|
|
18
|
+
declare class MfeBridge {
|
|
19
|
+
private middlewares;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to events on a specific channel
|
|
22
|
+
* @template T Type of payload data
|
|
23
|
+
* @param channel The channel to subscribe to
|
|
24
|
+
* @param callback Function to call when an event occurs on this channel
|
|
25
|
+
* @returns Unsubscribe function to remove the event listener
|
|
26
|
+
*/
|
|
27
|
+
subscribe<T = any>(channel: string, callback: Callback<T>): () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Publish an event to a specific channel
|
|
30
|
+
* @template T Type of payload data
|
|
31
|
+
* @param channel The channel to publish to
|
|
32
|
+
* @param payload Data to send with the event
|
|
33
|
+
*/
|
|
34
|
+
publish<T = any>(channel: string, payload: T): void;
|
|
35
|
+
/**
|
|
36
|
+
* Add middleware to intercept events before they're published
|
|
37
|
+
* @param middleware Function that can inspect or modify events
|
|
38
|
+
*/
|
|
39
|
+
use(middleware: Middleware): void;
|
|
40
|
+
/**
|
|
41
|
+
* Remove all middleware
|
|
42
|
+
*/
|
|
43
|
+
clearMiddlewares(): void;
|
|
44
|
+
}
|
|
45
|
+
export declare const mfeBridge: MfeBridge;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnchorHTMLAttributes, type FC } from 'react';
|
|
2
|
+
export declare const NAVIGATION_CHANNELS: {
|
|
3
|
+
NAVIGATE: string;
|
|
4
|
+
};
|
|
5
|
+
export type AppSite = 'client' | 'home' | 'music';
|
|
6
|
+
export type IMfeNavigateHref = {
|
|
7
|
+
primaryHref: string;
|
|
8
|
+
secondaryHref?: string;
|
|
9
|
+
};
|
|
10
|
+
export interface IMfeNavigate {
|
|
11
|
+
primaryHref: string;
|
|
12
|
+
secondaryHref?: string;
|
|
13
|
+
internal?: boolean;
|
|
14
|
+
site?: AppSite;
|
|
15
|
+
options?: any;
|
|
16
|
+
target?: '_self' | '_blank';
|
|
17
|
+
}
|
|
18
|
+
export declare const useMfeNavigate: () => {
|
|
19
|
+
navigate: (params: IMfeNavigate) => void;
|
|
20
|
+
};
|
|
21
|
+
export interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
|
|
22
|
+
internal?: boolean;
|
|
23
|
+
primaryHref: string;
|
|
24
|
+
secondaryHref?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const MfeLink: FC<IMfeLinkProps>;
|
|
27
|
+
export type NavigateFunction<O = any> = (path: string, options?: O) => void;
|
|
28
|
+
export interface IMfeNavigateReactProviderProps {
|
|
29
|
+
navigate: NavigateFunction;
|
|
30
|
+
}
|
|
31
|
+
export declare const MfeNavigateReactProvider: FC<IMfeNavigateReactProviderProps>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for mfe-shared library
|
|
3
|
+
*
|
|
4
|
+
* This file is used to re-export all types from the library
|
|
5
|
+
* to ensure they're available to consumers.
|
|
6
|
+
*/
|
|
7
|
+
export * from './auth.types';
|
|
8
|
+
export type { IAuthProviderProps } from './auth';
|
|
9
|
+
export type { HydrationState } from './hydration-helper';
|
|
10
|
+
export type { AppSite, IMfeNavigate, IMfeNavigateHref, IMfeLinkProps, NavigateFunction, IMfeNavigateReactProviderProps } from './navigation';
|
|
11
|
+
export type { ICartItem } from './cart';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dinocollab-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -39,17 +39,8 @@
|
|
|
39
39
|
"http-service": [
|
|
40
40
|
"./dist/types/http-service/index.d.ts"
|
|
41
41
|
],
|
|
42
|
-
"mfe-
|
|
43
|
-
"./dist/types/mfe-
|
|
44
|
-
],
|
|
45
|
-
"mfe-modules": [
|
|
46
|
-
"./dist/types/mfe-modules/index.d.ts"
|
|
47
|
-
],
|
|
48
|
-
"mfe-modules/react": [
|
|
49
|
-
"./dist/types/mfe-modules/react/index.d.ts"
|
|
50
|
-
],
|
|
51
|
-
"mfe-modules/nextjs": [
|
|
52
|
-
"./dist/types/mfe-modules/nextjs/index.d.ts"
|
|
42
|
+
"mfe-shared": [
|
|
43
|
+
"./dist/types/mfe-shared/index.d.ts"
|
|
53
44
|
],
|
|
54
45
|
"redux": [
|
|
55
46
|
"./dist/types/redux/index.d.ts"
|
|
@@ -94,21 +85,9 @@
|
|
|
94
85
|
"import": "./dist/http-service/index.js",
|
|
95
86
|
"types": "./dist/types/http-service/index.d.ts"
|
|
96
87
|
},
|
|
97
|
-
"./mfe-
|
|
98
|
-
"import": "./dist/mfe-
|
|
99
|
-
"types": "./dist/types/mfe-
|
|
100
|
-
},
|
|
101
|
-
"./mfe-modules": {
|
|
102
|
-
"import": "./dist/mfe-modules/index.js",
|
|
103
|
-
"types": "./dist/types/mfe-modules/index.d.ts"
|
|
104
|
-
},
|
|
105
|
-
"./mfe-modules/react": {
|
|
106
|
-
"import": "./dist/mfe-modules/react/index.js",
|
|
107
|
-
"types": "./dist/types/mfe-modules/react/index.d.ts"
|
|
108
|
-
},
|
|
109
|
-
"./mfe-modules/nextjs": {
|
|
110
|
-
"import": "./dist/mfe-modules/nextjs/index.js",
|
|
111
|
-
"types": "./dist/types/mfe-modules/nextjs/index.d.ts"
|
|
88
|
+
"./mfe-shared": {
|
|
89
|
+
"import": "./dist/mfe-shared/index.js",
|
|
90
|
+
"types": "./dist/types/mfe-shared/index.d.ts"
|
|
112
91
|
},
|
|
113
92
|
"./utils": {
|
|
114
93
|
"import": "./dist/utils/index.js",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var n,a,e;!function(n){n[n.And=0]="And",n[n.Or=1]="Or"}(n||(n={})),function(n){n[n.GreaterThan=0]="GreaterThan",n[n.LessThan=1]="LessThan",n[n.GreaterThanOrEqual=2]="GreaterThanOrEqual",n[n.LessThanOrEqual=3]="LessThanOrEqual",n[n.NotEqual=4]="NotEqual",n[n.Equal=5]="Equal",n[n.Contains=6]="Contains"}(a||(a={})),function(n){n[n.Ascending=0]="Ascending",n[n.Descending=1]="Descending"}(e||(e={}));export{n as ELogic,a as EOperator,e as EOrder};
|
|
2
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/http-service/base/types.ts"],"sourcesContent":["export enum ELogic {\r\n And,\r\n Or\r\n}\r\n\r\nexport enum EOperator {\r\n GreaterThan,\r\n LessThan,\r\n GreaterThanOrEqual,\r\n LessThanOrEqual,\r\n NotEqual,\r\n Equal,\r\n Contains\r\n}\r\n\r\nexport enum EOrder {\r\n Ascending,\r\n Descending\r\n}\r\n\r\ninterface IFilterField<T> {\r\n Logic?: ELogic\r\n Operator?: EOperator\r\n FieldName: keyof T\r\n Value: string\r\n}\r\n\r\ninterface IFilterScope<T> {\r\n Logic?: ELogic\r\n Scopes: IPropFilter<T>[]\r\n}\r\n\r\nexport type IPropFilter<T> = IFilterField<T> | IFilterScope<T>\r\n\r\nexport interface IPropOrderBy<T> {\r\n Type: EOrder\r\n FieldName: keyof T\r\n}\r\n\r\nexport interface IFilterModelSwagger<T> {\r\n Page?: number\r\n Amount?: number\r\n PropFilters?: IPropFilter<T>[]\r\n PropOrders?: IPropOrderBy<T>[]\r\n}\r\n\r\nexport interface IReponseAll<T> {\r\n Data?: T[]\r\n Total?: number\r\n Page?: number\r\n Amount?: number\r\n}\r\n"],"names":["ELogic","EOperator","EOrder"],"mappings":"IAAYA,EAKAC,EAUAC,GAfZ,SAAYF,GACVA,EAAAA,EAAA,IAAA,GAAA,MACAA,EAAAA,EAAA,GAAA,GAAA,IACD,CAHD,CAAYA,IAAAA,EAGX,CAAA,IAED,SAAYC,GACVA,EAAAA,EAAA,YAAA,GAAA,cACAA,EAAAA,EAAA,SAAA,GAAA,WACAA,EAAAA,EAAA,mBAAA,GAAA,qBACAA,EAAAA,EAAA,gBAAA,GAAA,kBACAA,EAAAA,EAAA,SAAA,GAAA,WACAA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,SAAA,GAAA,UACD,CARD,CAAYA,IAAAA,EAQX,CAAA,IAED,SAAYC,GACVA,EAAAA,EAAA,UAAA,GAAA,YACAA,EAAAA,EAAA,WAAA,GAAA,YACD,CAHD,CAAYA,IAAAA,EAGX,CAAA"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{slicedToArray as t,toConsumableArray as e}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsxs as o,jsx as n}from"react/jsx-runtime";import{useState as i,useEffect as r}from"react";var a=function(){var a=i([]),l=t(a,2),s=l[0],d=l[1];return r((function(){var t=function(t){var o=t.detail,n=o.to,i=o.options;d((function(t){return[{to:n,options:i}].concat(e(t.slice(0,9)))}))};return globalThis.addEventListener("mfe:navigate",t),function(){return globalThis.removeEventListener("mfe:navigate",t)}}),[]),o("div",{style:{position:"fixed",bottom:16,left:16,background:"rgba(0,0,0,0.8)",color:"#fff",padding:12,borderRadius:8,fontSize:12,zIndex:9999,maxWidth:320,maxHeight:240,overflowY:"auto",boxShadow:"0 2px 8px rgba(0,0,0,0.2)"},children:[n("div",{style:{fontWeight:"bold",marginBottom:8},children:"MFE Navigate Debug"}),0===s.length?n("div",{style:{opacity:.7},children:"No navigation events"}):n("ul",{style:{margin:0,padding:0,listStyle:"none"},children:s.map((function(t,e){var i;return o("li",{style:{marginBottom:4},children:[n("span",{style:{color:"#90ee90"},children:t.to}),(null===(i=t.options)||void 0===i?void 0:i.target)&&o("span",{style:{color:"#87ceeb",marginLeft:8},children:["(",t.options.target,")"]})]},e)}))})]})};export{a as MfeNavigateDebugPanel};
|
|
2
|
-
//# sourceMappingURL=mfe-navigate.debug.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mfe-navigate.debug.js","sources":["../../src/mfe-modules/mfe-navigate.debug.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\r\nimport type { MfeNavigate } from './types'\r\n\r\nconst MAX_EVENTS = 10\r\n\r\nexport const MfeNavigateDebugPanel: React.FC = () => {\r\n const [debugEvents, setDebugEvents] = useState<MfeNavigate[]>([])\r\n\r\n useEffect(() => {\r\n const handleNavigate = (e: CustomEvent) => {\r\n const { to, options } = e.detail as MfeNavigate\r\n setDebugEvents((events) => [{ to, options }, ...events.slice(0, MAX_EVENTS - 1)])\r\n }\r\n globalThis.addEventListener('mfe:navigate', handleNavigate as EventListener)\r\n return () => globalThis.removeEventListener('mfe:navigate', handleNavigate as EventListener)\r\n }, [])\r\n\r\n return (\r\n <div\r\n style={{\r\n position: 'fixed',\r\n bottom: 16,\r\n left: 16,\r\n background: 'rgba(0,0,0,0.8)',\r\n color: '#fff',\r\n padding: 12,\r\n borderRadius: 8,\r\n fontSize: 12,\r\n zIndex: 9999,\r\n maxWidth: 320,\r\n maxHeight: 240,\r\n overflowY: 'auto',\r\n boxShadow: '0 2px 8px rgba(0,0,0,0.2)'\r\n }}\r\n >\r\n <div style={{ fontWeight: 'bold', marginBottom: 8 }}>MFE Navigate Debug</div>\r\n {debugEvents.length === 0 ? (\r\n <div style={{ opacity: 0.7 }}>No navigation events</div>\r\n ) : (\r\n <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>\r\n {debugEvents.map((ev, idx) => (\r\n <li key={idx} style={{ marginBottom: 4 }}>\r\n <span style={{ color: '#90ee90' }}>{ev.to}</span>\r\n {ev.options?.target && <span style={{ color: '#87ceeb', marginLeft: 8 }}>({ev.options.target})</span>}\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["MfeNavigateDebugPanel","_useState","useState","_useState2","_slicedToArray","debugEvents","setDebugEvents","useEffect","handleNavigate","e","_e$detail","detail","to","options","events","concat","_toConsumableArray","slice","MAX_EVENTS","globalThis","addEventListener","removeEventListener","_jsxs","style","position","bottom","left","background","color","padding","borderRadius","fontSize","zIndex","maxWidth","maxHeight","overflowY","boxShadow","children","_jsx","fontWeight","marginBottom","length","opacity","margin","listStyle","map","ev","idx","_ev$options","target","marginLeft"],"mappings":"kMAGA,IAEaA,EAAkC,WAC7C,IAAAC,EAAsCC,EAAwB,IAAGC,EAAAC,EAAAH,EAAA,GAA1DI,EAAWF,EAAA,GAAEG,EAAcH,EAAA,GAWlC,OATAI,GAAU,WACR,IAAMC,EAAiB,SAACC,GACtB,IAAAC,EAAwBD,EAAEE,OAAlBC,EAAEF,EAAFE,GAAIC,EAAOH,EAAPG,QACZP,GAAe,SAACQ,GAAM,MAAM,CAAA,CAAEF,GAAAA,EAAIC,QAAAA,IAASE,OAAAC,EAAKF,EAAOG,MAAM,EAAGC,IAAe,GAChF,EAED,OADAC,WAAWC,iBAAiB,eAAgBZ,GACrC,WAAA,OAAMW,WAAWE,oBAAoB,eAAgBb,EAAgC,CAC7F,GAAE,IAGDc,EACE,MAAA,CAAAC,MAAO,CACLC,SAAU,QACVC,OAAQ,GACRC,KAAM,GACNC,WAAY,kBACZC,MAAO,OACPC,QAAS,GACTC,aAAc,EACdC,SAAU,GACVC,OAAQ,KACRC,SAAU,IACVC,UAAW,IACXC,UAAW,OACXC,UAAW,6BAGbC,SAAA,CAAAC,EAAA,MAAA,CAAKf,MAAO,CAAEgB,WAAY,OAAQC,aAAc,GAAGH,SAAA,uBAC3B,IAAvBhC,EAAYoC,OACXH,EAAK,MAAA,CAAAf,MAAO,CAAEmB,QAAS,IAAiCL,SAAA,yBAExDC,EAAI,KAAA,CAAAf,MAAO,CAAEoB,OAAQ,EAAGd,QAAS,EAAGe,UAAW,QAC5CP,SAAAhC,EAAYwC,KAAI,SAACC,EAAIC,GAAG,IAAAC,EAAA,OACvB1B,EAAA,KAAA,CAAcC,MAAO,CAAEiB,aAAc,GAAGH,SAAA,CACtCC,EAAM,OAAA,CAAAf,MAAO,CAAEK,MAAO,WAAcS,SAAAS,EAAGlC,MAC5B,QAAVoC,EAAAF,EAAGjC,eAAO,IAAAmC,OAAA,EAAVA,EAAYC,SAAU3B,EAAM,OAAA,CAAAC,MAAO,CAAEK,MAAO,UAAWsB,WAAY,GAAOb,SAAA,CAAA,IAAAS,EAAGjC,QAAQoC,OAAe,SAF9FF,EAIV,QAKX"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{objectWithoutProperties as t,objectSpread2 as e}from"../_virtual/_rollupPluginBabelHelpers.js";import{jsx as n}from"react/jsx-runtime";var r=["to","isInternal"],a=function(){return{navigate:function(t){globalThis.dispatchEvent(new CustomEvent("mfe:navigate",{detail:t}))}}},i=function(i){var o=i.to,l=i.isInternal,u=t(i,r),s=a().navigate;return n("a",e(e({},u),{},{href:o,onClick:function(t){o&&l&&(t.preventDefault(),s({to:o}))}}))};export{i as MfeLink,a as useMfeNavigate};
|
|
2
|
-
//# sourceMappingURL=mfe-navigate.remote.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mfe-navigate.remote.js","sources":["../../src/mfe-modules/mfe-navigate.remote.tsx"],"sourcesContent":["import React, { AnchorHTMLAttributes, FC } from 'react'\r\nimport type { MfeNavigate } from './types'\r\n\r\nexport const useMfeNavigate = () => {\r\n const navigate = (params: MfeNavigate) => {\r\n globalThis.dispatchEvent(new CustomEvent('mfe:navigate', { detail: params }))\r\n }\r\n return { navigate }\r\n}\r\n\r\nexport interface IMfeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\r\n to?: string\r\n isInternal?: boolean\r\n}\r\n\r\nexport const MfeLink: FC<IMfeLinkProps> = (props) => {\r\n const { to, isInternal, ...rest } = props\r\n const { navigate } = useMfeNavigate()\r\n\r\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (to && isInternal) {\r\n e.preventDefault()\r\n navigate({ to })\r\n }\r\n }\r\n\r\n return <a {...rest} href={to} onClick={handleClick} />\r\n}\r\n"],"names":["useMfeNavigate","navigate","params","globalThis","dispatchEvent","CustomEvent","detail","MfeLink","props","to","isInternal","rest","_objectWithoutProperties","_excluded","_jsx","_objectSpread","href","onClick","e","preventDefault"],"mappings":"wKAGaA,EAAiB,WAI5B,MAAO,CAAEC,SAHQ,SAACC,GAChBC,WAAWC,cAAc,IAAIC,YAAY,eAAgB,CAAEC,OAAQJ,IACpE,EAEH,EAOaK,EAA6B,SAACC,GACzC,IAAQC,EAA4BD,EAA5BC,GAAIC,EAAwBF,EAAxBE,WAAeC,EAAIC,EAAKJ,EAAKK,GACjCZ,EAAaD,IAAbC,SASR,OAAOa,EAAA,IAAAC,EAAAA,KAAOJ,GAAI,GAAA,CAAEK,KAAMP,EAAIQ,QAPV,SAACC,GACfT,GAAMC,IACRQ,EAAEC,iBACFlB,EAAS,CAAEQ,GAAAA,IAEd,IAGH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sources":["../../../src/mfe-modules/nextjs/provider.tsx"],"sourcesContent":["import { FC } from 'react'\r\n\r\nexport const MfeNavigateNextProvider: FC = () => {\r\n return <>Next Provider</>\r\n}\r\n"],"names":["MfeNavigateNextProvider","_jsx"],"mappings":"0DAEaA,EAA8B,WACzC,OAAOC,+BACT"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useEffect as n}from"react";var r=function(){var r=function(){try{return require("react-router-dom").useNavigate()}catch(e){return console.warn("react-router-dom not available, using fallback"),function(){console.warn("Navigate function is not available. Please ensure react-router-dom is installed.")}}}();return n((function(){var e=function(e){var t=e.detail,n=t.to,a=t.options;n&&("_blank"!==(null==a?void 0:a.target)?r(n,a):globalThis.open("".concat(n),"_blank"))};return globalThis.addEventListener("mfe:navigate",e),function(){return globalThis.removeEventListener("mfe:navigate",e)}}),[r]),e(t,{})};export{r as MfeNavigateReactProvider};
|
|
2
|
-
//# sourceMappingURL=provider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sources":["../../../src/mfe-modules/react/provider.tsx"],"sourcesContent":["import React, { FC, useEffect } from 'react'\r\nimport { MfeNavigate } from '../types'\r\n\r\n// Define types to avoid direct imports\r\nexport type NavigateFunction = (path: string, options?: any) => void\r\n\r\n// Use hook-style functions that don't directly import from react-router-dom\r\nfunction useReactNavigate(): NavigateFunction {\r\n try {\r\n // @ts-ignore - Ignore TS errors during build time\r\n return require('react-router-dom').useNavigate()\r\n } catch (error) {\r\n console.warn('react-router-dom not available, using fallback')\r\n // Provide fallback implementation\r\n return () => {\r\n console.warn('Navigate function is not available. Please ensure react-router-dom is installed.')\r\n }\r\n }\r\n}\r\n\r\nexport const MfeNavigateReactProvider: FC = () => {\r\n const navigate = useReactNavigate()\r\n\r\n useEffect(() => {\r\n const handleNavigate = (e: CustomEvent) => {\r\n const { to, options } = e.detail as MfeNavigate\r\n if (!to) return\r\n if (options?.target === '_blank') {\r\n globalThis.open(`${to}`, '_blank')\r\n return\r\n }\r\n navigate(to, options)\r\n }\r\n globalThis.addEventListener('mfe:navigate', handleNavigate as EventListener)\r\n return () => globalThis.removeEventListener('mfe:navigate', handleNavigate as EventListener)\r\n }, [navigate])\r\n return <></>\r\n}\r\n"],"names":["MfeNavigateReactProvider","navigate","require","useNavigate","error","console","warn","useReactNavigate","useEffect","handleNavigate","e","_e$detail","detail","to","options","target","globalThis","open","concat","addEventListener","removeEventListener","_jsx"],"mappings":"4FAoBaA,EAA+B,WAC1C,IAAMC,EAdR,WACE,IAEE,OAAOC,QAAQ,oBAAoBC,aACpC,CAAC,MAAOC,GAGP,OAFAC,QAAQC,KAAK,kDAEN,WACLD,QAAQC,KAAK,mFACd,CACF,CACH,CAGmBC,GAejB,OAbAC,GAAU,WACR,IAAMC,EAAiB,SAACC,GACtB,IAAAC,EAAwBD,EAAEE,OAAlBC,EAAEF,EAAFE,GAAIC,EAAOH,EAAPG,QACPD,IACmB,YAApBC,aAAO,EAAPA,EAASC,QAIbd,EAASY,EAAIC,GAHXE,WAAWC,KAAIC,GAAAA,OAAIL,GAAM,UAI5B,EAED,OADAG,WAAWG,iBAAiB,eAAgBV,GACrC,WAAA,OAAMO,WAAWI,oBAAoB,eAAgBX,EAAgC,CAC9F,GAAG,CAACR,IACGoB,OACT"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|