@m4l/layouts 1.0.4

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.
Files changed (32) hide show
  1. package/dist/hooks/index.d.ts +2 -0
  2. package/dist/hooks/useMasterDetail/index.d.ts +1 -0
  3. package/dist/hooks/useMasterDetail/index.js +4 -0
  4. package/dist/hooks/useModule/index.d.ts +2 -0
  5. package/dist/hooks/useModule/index.js +9 -0
  6. package/dist/hooks/useResponsive.d.ts +8 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.js +12 -0
  9. package/dist/layouts/MasterDetailLayout/components/ButtonDetail/index.d.ts +3 -0
  10. package/dist/layouts/MasterDetailLayout/contexts/MasterDetailContext/index.d.ts +5 -0
  11. package/dist/layouts/MasterDetailLayout/contexts/MasterDetailContext/types.d.ts +13 -0
  12. package/dist/layouts/MasterDetailLayout/dicctionary.d.ts +3 -0
  13. package/dist/layouts/MasterDetailLayout/index.d.ts +3 -0
  14. package/dist/layouts/MasterDetailLayout/index.js +170 -0
  15. package/dist/layouts/MasterDetailLayout/types.d.ts +10 -0
  16. package/dist/layouts/ModuleLayout/components/Header/index.d.ts +2 -0
  17. package/dist/layouts/ModuleLayout/components/Header/skeleton.d.ts +2 -0
  18. package/dist/layouts/ModuleLayout/components/Header/styles.d.ts +8 -0
  19. package/dist/layouts/ModuleLayout/components/Header/types.d.ts +2 -0
  20. package/dist/layouts/ModuleLayout/components/ModuleContent/index.d.ts +3 -0
  21. package/dist/layouts/ModuleLayout/components/ModuleContent/styles.d.ts +3 -0
  22. package/dist/layouts/ModuleLayout/components/ModuleContent/types.d.ts +9 -0
  23. package/dist/layouts/ModuleLayout/contexts/ModuleContext/index.d.ts +5 -0
  24. package/dist/layouts/ModuleLayout/contexts/ModuleContext/types.d.ts +18 -0
  25. package/dist/layouts/ModuleLayout/dicctionary.d.ts +3 -0
  26. package/dist/layouts/ModuleLayout/index.d.ts +3 -0
  27. package/dist/layouts/ModuleLayout/index.js +380 -0
  28. package/dist/layouts/ModuleLayout/types.d.ts +28 -0
  29. package/dist/layouts/index.d.ts +2 -0
  30. package/dist/vendor.js +35 -0
  31. package/dist/vite-env.d.ts +3 -0
  32. package/package.json +72 -0
@@ -0,0 +1,2 @@
1
+ export * from './useMasterDetail';
2
+ export * from './useModule';
@@ -0,0 +1 @@
1
+ export declare const useMasterDetail: () => import("../../layouts/MasterDetailLayout/contexts/MasterDetailContext/types").MasterDetailContextProps;
@@ -0,0 +1,4 @@
1
+ import { useContext } from "react";
2
+ import { M as MasterDetailContext } from "../../layouts/MasterDetailLayout/index.js";
3
+ const useMasterDetail = () => useContext(MasterDetailContext);
4
+ export { useMasterDetail as u };
@@ -0,0 +1,2 @@
1
+ export declare const useModule: () => import("../../layouts/ModuleLayout/contexts/ModuleContext/types").ModuleLayoutContextProps;
2
+ export default useModule;
@@ -0,0 +1,9 @@
1
+ import { useContext } from "react";
2
+ import { M as ModuleContext } from "../../layouts/ModuleLayout/index.js";
3
+ const useModule = () => {
4
+ const context = useContext(ModuleContext);
5
+ if (!context)
6
+ throw new Error("useModule context must be use inside ModuleContext");
7
+ return context;
8
+ };
9
+ export { useModule as u };
@@ -0,0 +1,8 @@
1
+ import { Breakpoint } from '@mui/material';
2
+ declare type Query = 'up' | 'down' | 'between' | 'only';
3
+ declare type Key = Breakpoint | number;
4
+ declare type Start = Breakpoint | number;
5
+ declare type End = Breakpoint | number;
6
+ export declare function useResponsive(query: Query, key?: Key, start?: Start, end?: End): boolean | undefined;
7
+ export declare function useResponsiveDesktop(): boolean | undefined;
8
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './layouts';
2
+ export * from './hooks';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export { a as MasterDetailLayout } from "./layouts/MasterDetailLayout/index.js";
2
+ export { a as ModuleLayout } from "./layouts/ModuleLayout/index.js";
3
+ export { u as useMasterDetail } from "./hooks/useMasterDetail/index.js";
4
+ export { u as useModule } from "./hooks/useModule/index.js";
5
+ import "react";
6
+ import "@m4l/core";
7
+ import "@m4l/components";
8
+ import "react/jsx-runtime";
9
+ import "./vendor.js";
10
+ import "@mui/material/styles";
11
+ import "@mui/material/useMediaQuery";
12
+ import "@mui/material";
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { ComponentActionProps } from '@m4l/components';
3
+ export declare function ButtonDetail(props: ComponentActionProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import { MasterDetailContextProps, MasterDetailProviderProps } from './types';
3
+ declare const MasterDetailContext: import("react").Context<MasterDetailContextProps>;
4
+ declare function MasterDetailProvider(props: MasterDetailProviderProps): JSX.Element;
5
+ export { MasterDetailProvider, MasterDetailContext };
@@ -0,0 +1,13 @@
1
+ import { ReactNode } from 'react';
2
+ export declare type MasterSelecion = any | any[] | undefined;
3
+ export interface MasterDetailContextStateProps {
4
+ masterSelection?: MasterSelecion;
5
+ }
6
+ export interface MasterDetailProviderProps {
7
+ masterSelection: MasterSelecion;
8
+ setMasterSelection: (newMasterSelecion: MasterSelecion) => void;
9
+ children: ReactNode;
10
+ }
11
+ export interface MasterDetailContextProps extends MasterDetailContextStateProps {
12
+ onChangeMasterSelection: (newMasterSelection: MasterSelecion) => void;
13
+ }
@@ -0,0 +1,3 @@
1
+ import type { Dictionary } from '@m4l/core';
2
+ export declare function getMasterDetailLayoutComponentsDictionary(): string[];
3
+ export declare const defaultMasterDetailDictionary: Dictionary;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { MasterDetailLayoutProps } from './types';
3
+ export declare function MasterDetailLayout(props: MasterDetailLayoutProps): JSX.Element;
@@ -0,0 +1,170 @@
1
+ import { createContext, useState, useRef, useCallback, useMemo } from "react";
2
+ import { voidFunction, useEnvironment } from "@m4l/core";
3
+ import { SplitLayout } from "@m4l/components";
4
+ import { g as getModuleLayoutComponentsDictionary, d as defaultModuleLayoutDictionary, a as ModuleLayout } from "../ModuleLayout/index.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { u as useResponsiveDesktop } from "../../vendor.js";
7
+ import { Button } from "@mui/material";
8
+ import { u as useMasterDetail } from "../../hooks/useMasterDetail/index.js";
9
+ function getMasterDetailLayoutComponentsDictionary() {
10
+ return ["master_detail_layout"].concat(getModuleLayoutComponentsDictionary());
11
+ }
12
+ const defaultMasterDetailDictionary = {
13
+ master_detail_layout: {
14
+ split_vertical: "Split vertically",
15
+ split_horizontal: "Split horizontally",
16
+ no_split: "No split",
17
+ view_detail: "View detail"
18
+ },
19
+ ...defaultModuleLayoutDictionary
20
+ };
21
+ const initialState = {
22
+ masterSelection: void 0,
23
+ onChangeMasterSelection: voidFunction
24
+ };
25
+ const MasterDetailContext = createContext(initialState);
26
+ function MasterDetailProvider(props) {
27
+ const {
28
+ children,
29
+ masterSelection,
30
+ setMasterSelection
31
+ } = props;
32
+ const onChangeMasterSelection = (newMasterSelection) => {
33
+ setMasterSelection(newMasterSelection);
34
+ };
35
+ return /* @__PURE__ */ jsx(MasterDetailContext.Provider, {
36
+ value: {
37
+ masterSelection,
38
+ onChangeMasterSelection
39
+ },
40
+ children
41
+ });
42
+ }
43
+ function ButtonDetail(props) {
44
+ const {
45
+ masterSelection
46
+ } = useMasterDetail();
47
+ const {
48
+ onClick,
49
+ description
50
+ } = props;
51
+ return /* @__PURE__ */ jsx(Button, {
52
+ onClick,
53
+ variant: "outlined",
54
+ disabled: masterSelection === void 0 ? true : false,
55
+ children: description
56
+ }, "miDetail");
57
+ }
58
+ function getTotalModuleActions(splitActions, moduleActions, viewDetailAction, isDesktop) {
59
+ let totalActions = isDesktop !== void 0 && isDesktop ? [...splitActions] : [viewDetailAction];
60
+ totalActions = totalActions.concat(moduleActions);
61
+ return totalActions;
62
+ }
63
+ function MasterDetailLayout(props) {
64
+ const {
65
+ moduleId,
66
+ moduleNameField,
67
+ detailComponent,
68
+ initialModuleActions: moduleActions,
69
+ urlIcon,
70
+ masterComponent,
71
+ defaultDictionary,
72
+ componentsDictionary,
73
+ breadcrumbLinks
74
+ } = props;
75
+ const {
76
+ host_static_assets,
77
+ environment
78
+ } = useEnvironment();
79
+ const [splitPosition, setSplitPosition] = useState("vertical");
80
+ const isDesktop = useResponsiveDesktop();
81
+ const moduleLayoutRef = useRef(null);
82
+ const [masterSelection, setMasterSelection] = useState(void 0);
83
+ const onChangePostionInternal = (newPostion) => {
84
+ const newSplitActions = [...initialSplitActions];
85
+ for (let i = 0; i < newSplitActions.length; i++) {
86
+ newSplitActions[i].disabled = false;
87
+ if (newSplitActions[i].tag === newPostion) {
88
+ newSplitActions[i].disabled = true;
89
+ }
90
+ }
91
+ setSplitActions(newSplitActions);
92
+ setSplitPosition(newPostion);
93
+ };
94
+ const initialSplitActions = [{
95
+ urlIcon: `${host_static_assets}/${environment}/frontend/components/masterdetaillayout/assets/icons/split_vertical.svg`,
96
+ onClick: () => onChangePostionInternal("vertical"),
97
+ disabled: true,
98
+ visibility: "main",
99
+ dictionaryField: "master_detail_layout.split_vertical",
100
+ tag: "vertical",
101
+ className: "splitactions"
102
+ }, {
103
+ urlIcon: `${host_static_assets}/${environment}/frontend/components/masterdetaillayout/assets/icons/split_horizontal.svg`,
104
+ onClick: () => onChangePostionInternal("horizontal"),
105
+ disabled: false,
106
+ visibility: "main",
107
+ dictionaryField: "master_detail_layout.split_horizontal",
108
+ tag: "horizontal",
109
+ className: "splitactions"
110
+ }, {
111
+ urlIcon: `${host_static_assets}/${environment}/frontend/components/masterdetaillayout/assets/icons/no_split.svg`,
112
+ onClick: () => onChangePostionInternal("none"),
113
+ disabled: false,
114
+ visibility: "main",
115
+ dictionaryField: "master_detail_layout.no_split",
116
+ tag: "none",
117
+ className: "splitactions"
118
+ }];
119
+ const onClickViewDetail = useCallback(() => {
120
+ moduleLayoutRef.current?.openModal({
121
+ title: "master_detail_layout.view_detail",
122
+ initialWidth: 500,
123
+ initialHeigth: 680,
124
+ contentComponent: detailComponent,
125
+ actionComponents: void 0
126
+ });
127
+ }, [detailComponent]);
128
+ const viewDetailAction = useMemo(() => {
129
+ return {
130
+ urlIcon: `${host_static_assets}/${environment}/frontend/components/masterdetaillayout/assets/icons/view_detail.svg`,
131
+ onClick: onClickViewDetail,
132
+ disabled: false,
133
+ visibility: "allways",
134
+ dictionaryField: "master_detail_layout.view_detail",
135
+ tag: "none",
136
+ className: "",
137
+ component: ButtonDetail
138
+ };
139
+ }, [environment, onClickViewDetail]);
140
+ const [splitActions, setSplitActions] = useState(initialSplitActions);
141
+ const finalModuleActions = useMemo(() => {
142
+ const actions = getTotalModuleActions(splitActions, moduleActions, viewDetailAction, isDesktop);
143
+ return actions;
144
+ }, [splitActions, moduleActions, isDesktop, viewDetailAction]);
145
+ const finalComponentsDictionary = useMemo(() => componentsDictionary.concat(getMasterDetailLayoutComponentsDictionary()), [componentsDictionary]);
146
+ const finalDefaultDictionary = useMemo(() => ({
147
+ ...defaultDictionary,
148
+ ...defaultMasterDetailDictionary
149
+ }), [defaultDictionary]);
150
+ return /* @__PURE__ */ jsx(MasterDetailProvider, {
151
+ masterSelection,
152
+ setMasterSelection,
153
+ children: /* @__PURE__ */ jsx(ModuleLayout, {
154
+ ref: moduleLayoutRef,
155
+ moduleId,
156
+ moduleNameField,
157
+ urlIcon,
158
+ initialModuleActions: finalModuleActions,
159
+ defaultDictionary: finalDefaultDictionary,
160
+ componentsDictionary: finalComponentsDictionary,
161
+ breadcrumbLinks,
162
+ children: /* @__PURE__ */ jsx(SplitLayout, {
163
+ splitPosition: isDesktop ? splitPosition : "none",
164
+ firstPart: masterComponent,
165
+ secondPart: detailComponent
166
+ })
167
+ })
168
+ });
169
+ }
170
+ export { MasterDetailContext as M, MasterDetailLayout as a };
@@ -0,0 +1,10 @@
1
+ import { ReactNode } from 'react';
2
+ import { ModuleLayoutProps } from '../ModuleLayout/types';
3
+ export interface ContainerProps {
4
+ vertical: boolean;
5
+ }
6
+ export interface MasterDetailLayoutProps extends Omit<ModuleLayoutProps, 'children'> {
7
+ masterComponent: ((props?: any) => JSX.Element) | ReactNode;
8
+ detailComponent: ((props?: any) => JSX.Element) | ReactNode;
9
+ onChangeSelected?: (row: any[]) => void;
10
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function Header(): JSX.Element;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function SKTModuleHeader(): JSX.Element;
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ export declare const Container: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
3
+ export declare const Wrapper: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
4
+ export declare const ModuleTitleContent: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
5
+ export declare const ModuleTitle: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
6
+ export declare const Separator: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
7
+ export declare const Breadcrumbs: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
8
+ export declare const ModuleActions: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -0,0 +1,2 @@
1
+ export interface HeaderProps {
2
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { ModuleProps, ModuleRef } from './types';
3
+ export declare const Module: import("react").ForwardRefExoticComponent<ModuleProps & import("react").RefAttributes<ModuleRef>>;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare const WrapperModule: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
3
+ export declare const ModuleContent: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ import { ModalOpenOptions } from '@m4l/components';
3
+ export declare type ModuleRef = {
4
+ openModal: (modalOpenProps: ModalOpenOptions) => void;
5
+ current: HTMLDivElement | null;
6
+ };
7
+ export interface ModuleProps {
8
+ children: ReactNode;
9
+ }
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import { ModuleLayoutContextProps, ModuleLayoutProviderProps } from './types';
3
+ declare const ModuleContext: import("react").Context<ModuleLayoutContextProps>;
4
+ declare function ModuleProvider(props: ModuleLayoutProviderProps): JSX.Element;
5
+ export { ModuleProvider, ModuleContext };
@@ -0,0 +1,18 @@
1
+ import type { TLink } from '@m4l/components';
2
+ import type { ReactNode } from 'react';
3
+ import type { ModuleAction } from '../../types';
4
+ export interface ModuleLayoutContextStateProps {
5
+ urlIcon: string;
6
+ moduleId: number;
7
+ moduleNameField: string;
8
+ breadcrumbLinks: TLink[];
9
+ }
10
+ export interface ModuleLayoutProviderProps extends Omit<ModuleLayoutContextStateProps, 'init'> {
11
+ children: ReactNode;
12
+ initialModuleActions: ModuleAction[];
13
+ }
14
+ export interface ModuleLayoutContextProps extends ModuleLayoutContextStateProps {
15
+ moduleActions: ModuleAction[];
16
+ dynamicActions: ModuleAction[];
17
+ setDynamicActions: (dynamicActions: ModuleAction[]) => void;
18
+ }
@@ -0,0 +1,3 @@
1
+ import type { Dictionary } from '@m4l/core';
2
+ export declare function getModuleLayoutComponentsDictionary(): string[];
3
+ export declare const defaultModuleLayoutDictionary: Dictionary;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { ModuleLayoutProps, ModuleLayoutRef } from './types';
3
+ export declare const ModuleLayout: import("react").ForwardRefExoticComponent<ModuleLayoutProps & import("react").RefAttributes<ModuleLayoutRef>>;
@@ -0,0 +1,380 @@
1
+ import { BoxIcon, Breadcrumbs as Breadcrumbs$1, MenuActions, useModal, ModalProvider, getModalDialogComponentsDictionary } from "@m4l/components";
2
+ import { createContext, useState, useMemo, forwardRef, useRef, useImperativeHandle } from "react";
3
+ import { styled, useTheme } from "@mui/material/styles";
4
+ import { voidFunction, useModuleDictionary, useFlagsPresent, FlagsProvider, ModuleDictionaryProvider } from "@m4l/core";
5
+ import { Skeleton, Typography, IconButton } from "@mui/material";
6
+ import { u as useResponsiveDesktop } from "../../vendor.js";
7
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
8
+ import { u as useModule } from "../../hooks/useModule/index.js";
9
+ const WrapperModule = styled("div")(() => ({
10
+ display: "flex",
11
+ flexDirection: "column",
12
+ position: "absolute",
13
+ margin: "12px",
14
+ left: "0px",
15
+ right: "0px",
16
+ top: "0px",
17
+ bottom: "0px",
18
+ overflow: "hidden"
19
+ }));
20
+ const ModuleContent = styled("div")(({
21
+ theme
22
+ }) => ({
23
+ display: "flex",
24
+ position: "relative",
25
+ marginTop: theme.spacing(2),
26
+ flexGrow: "1",
27
+ overflow: "hidden"
28
+ }));
29
+ const Container = styled("div")(({
30
+ theme
31
+ }) => ({
32
+ display: "flex",
33
+ position: "relative",
34
+ paddingTop: theme.spacing(2),
35
+ paddingBottom: theme.spacing(2),
36
+ borderBottom: `1px solid ${theme.palette.divider}`,
37
+ height: "72px",
38
+ overflow: "hidden",
39
+ alignItems: "center",
40
+ " > span": {
41
+ marginRight: "12px"
42
+ },
43
+ "& > h5": {
44
+ paddingRight: theme.spacing(3),
45
+ borderRight: `1px solid ${theme.palette.divider}`
46
+ },
47
+ " > nav": {
48
+ marginRight: "12px",
49
+ flexGrow: 1
50
+ },
51
+ "& .splitactions.Mui-disabled": {
52
+ color: theme.palette.primary.main
53
+ },
54
+ "& svg ": {
55
+ width: "20px",
56
+ height: "20px"
57
+ }
58
+ }));
59
+ const Wrapper = styled("div")(({
60
+ theme
61
+ }) => ({
62
+ display: "flex",
63
+ justifyContent: "space-between",
64
+ padding: `${theme.spacing(2)} 0`,
65
+ borderBottom: `1px solid ${theme.palette.divider}`,
66
+ height: "auto",
67
+ [theme.breakpoints.up("sm")]: {
68
+ height: theme.spacing(9)
69
+ }
70
+ }));
71
+ const ModuleTitleContent = styled("div")(({
72
+ theme
73
+ }) => ({
74
+ display: "grid",
75
+ gridTemplateColumns: "auto",
76
+ gridGap: theme.spacing(1.75),
77
+ alignItems: "center",
78
+ width: "auto",
79
+ height: "auto",
80
+ [theme.breakpoints.up("sm")]: {
81
+ gridTemplateColumns: "repeat(3, auto)"
82
+ }
83
+ }));
84
+ const ModuleTitle = styled("div")(({
85
+ theme
86
+ }) => ({
87
+ display: "grid",
88
+ gridTemplateColumns: `${theme.spacing(3)} auto`,
89
+ gridGap: theme.spacing(2),
90
+ alignItems: "center",
91
+ width: "auto",
92
+ height: "auto"
93
+ }));
94
+ const Separator = styled("div")(({
95
+ theme
96
+ }) => ({
97
+ display: "none",
98
+ alignItems: "center",
99
+ width: "1px",
100
+ background: theme.palette.divider,
101
+ height: "100%",
102
+ margin: `0 ${theme.spacing(2)}`,
103
+ [theme.breakpoints.up("sm")]: {
104
+ display: "flex"
105
+ }
106
+ }));
107
+ const Breadcrumbs = styled("div")(({
108
+ theme
109
+ }) => ({
110
+ display: "grid",
111
+ alignItems: "center",
112
+ gridTemplateColumns: `repeat(3, auto)`,
113
+ gridGap: theme.spacing(2)
114
+ }));
115
+ const ModuleActions = styled("div")(({
116
+ theme
117
+ }) => ({
118
+ display: "grid",
119
+ gridTemplateColumns: "auto",
120
+ alignItems: "center",
121
+ width: "auto",
122
+ height: "auto",
123
+ [theme.breakpoints.up("sm")]: {
124
+ gridTemplateColumns: `repeat(3, ${theme.spacing(3)})`,
125
+ gridGap: theme.spacing(2)
126
+ }
127
+ }));
128
+ function SKTModuleHeader() {
129
+ const isDesktop = useResponsiveDesktop();
130
+ return /* @__PURE__ */ jsxs(Wrapper, {
131
+ children: [/* @__PURE__ */ jsxs(ModuleTitleContent, {
132
+ children: [/* @__PURE__ */ jsxs(ModuleTitle, {
133
+ children: [/* @__PURE__ */ jsx(Skeleton, {
134
+ variant: "circular",
135
+ width: 24,
136
+ height: 24
137
+ }), /* @__PURE__ */ jsx(Skeleton, {
138
+ variant: "text",
139
+ width: 120,
140
+ height: 14
141
+ })]
142
+ }), /* @__PURE__ */ jsx(Separator, {}), /* @__PURE__ */ jsxs(Breadcrumbs, {
143
+ children: [/* @__PURE__ */ jsx(Skeleton, {
144
+ variant: "text",
145
+ width: 68,
146
+ height: 14
147
+ }), /* @__PURE__ */ jsx(Skeleton, {
148
+ variant: "circular",
149
+ width: 4,
150
+ height: 4
151
+ }), /* @__PURE__ */ jsx(Skeleton, {
152
+ variant: "text",
153
+ width: 68,
154
+ height: 14
155
+ })]
156
+ })]
157
+ }), /* @__PURE__ */ jsx(ModuleActions, {
158
+ children: isDesktop ? /* @__PURE__ */ jsxs(Fragment, {
159
+ children: [/* @__PURE__ */ jsx(Skeleton, {
160
+ variant: "circular",
161
+ width: 24,
162
+ height: 24
163
+ }), /* @__PURE__ */ jsx(Skeleton, {
164
+ variant: "circular",
165
+ width: 24,
166
+ height: 24
167
+ }), /* @__PURE__ */ jsx(Skeleton, {
168
+ variant: "circular",
169
+ width: 24,
170
+ height: 24
171
+ })]
172
+ }) : /* @__PURE__ */ jsx(Skeleton, {
173
+ variant: "circular",
174
+ width: 24,
175
+ height: 24
176
+ })
177
+ })]
178
+ });
179
+ }
180
+ const initialState = {
181
+ moduleId: 0,
182
+ moduleNameField: "module_name",
183
+ urlIcon: "",
184
+ moduleActions: [],
185
+ dynamicActions: [],
186
+ setDynamicActions: voidFunction,
187
+ breadcrumbLinks: []
188
+ };
189
+ const ModuleContext = createContext(initialState);
190
+ function ModuleProvider(props) {
191
+ const {
192
+ children,
193
+ initialModuleActions,
194
+ moduleId,
195
+ moduleNameField,
196
+ urlIcon,
197
+ breadcrumbLinks
198
+ } = props;
199
+ const [configOptions] = useState(() => ({
200
+ moduleId,
201
+ urlIcon,
202
+ moduleNameField,
203
+ dictionary: void 0,
204
+ breadcrumbLinks
205
+ }));
206
+ const [dynamicActions, setDynamicActions] = useState([]);
207
+ const finalModuleActions = useMemo(() => initialModuleActions.concat(dynamicActions), [initialModuleActions, dynamicActions]);
208
+ return /* @__PURE__ */ jsx(ModuleContext.Provider, {
209
+ value: {
210
+ moduleActions: finalModuleActions,
211
+ dynamicActions,
212
+ setDynamicActions,
213
+ moduleId: configOptions.moduleId,
214
+ moduleNameField: configOptions.moduleNameField,
215
+ urlIcon: configOptions.urlIcon,
216
+ breadcrumbLinks: configOptions.breadcrumbLinks
217
+ },
218
+ children
219
+ });
220
+ }
221
+ function getMenuActions(isDesktop, moduleActions) {
222
+ let menuActions = [...moduleActions.filter((action) => action.visibility !== "allways")];
223
+ if (isDesktop !== void 0 && isDesktop) {
224
+ menuActions = menuActions.filter((action) => action.visibility === "normal");
225
+ }
226
+ return menuActions;
227
+ }
228
+ function getMainActions(isDesktop, moduleActions) {
229
+ let mainActions = [];
230
+ if (isDesktop !== void 0 && isDesktop) {
231
+ mainActions = mainActions.concat(moduleActions.filter((action) => action.visibility === "main"));
232
+ }
233
+ mainActions = mainActions.concat(moduleActions.filter((action) => action.visibility === "allways"));
234
+ return mainActions;
235
+ }
236
+ function Header() {
237
+ const {
238
+ moduleActions,
239
+ moduleNameField,
240
+ breadcrumbLinks,
241
+ urlIcon
242
+ } = useModule();
243
+ const {
244
+ getLabel
245
+ } = useModuleDictionary();
246
+ const theme = useTheme();
247
+ const isDesktop = useResponsiveDesktop();
248
+ const isSkeleton = !useFlagsPresent(["dictionary_loaded"]);
249
+ const menuActions = useMemo(() => getMenuActions(isDesktop, moduleActions), [moduleActions, isDesktop]);
250
+ const mainActions = useMemo(() => {
251
+ console.log("useMemo Header ModuleActions mainActions", isDesktop, moduleActions);
252
+ return getMainActions(isDesktop, moduleActions);
253
+ }, [moduleActions, isDesktop]);
254
+ if (isSkeleton) {
255
+ return /* @__PURE__ */ jsx(SKTModuleHeader, {});
256
+ }
257
+ return /* @__PURE__ */ jsxs(Container, {
258
+ id: "Header",
259
+ children: [/* @__PURE__ */ jsx(BoxIcon, {
260
+ src: urlIcon,
261
+ sx: {
262
+ color: theme.palette.primary.main
263
+ }
264
+ }), /* @__PURE__ */ jsx(Typography, {
265
+ variant: "h5",
266
+ sx: {
267
+ maxWidth: 260,
268
+ overflow: "hidden",
269
+ whiteSpace: "nowrap",
270
+ color: "text.primary",
271
+ marginRight: "24px",
272
+ textOverflow: "ellipsis"
273
+ },
274
+ children: getLabel(moduleNameField)
275
+ }), /* @__PURE__ */ jsx(Breadcrumbs$1, {
276
+ links: breadcrumbLinks
277
+ }), mainActions.map((mainAction, index) => {
278
+ const description = getLabel(mainAction.dictionaryField);
279
+ if (!mainAction.component) {
280
+ return /* @__PURE__ */ jsx(IconButton, {
281
+ className: mainAction.className,
282
+ onClick: mainAction.onClick,
283
+ "aria-label": `${description}`,
284
+ disabled: mainAction.disabled,
285
+ children: /* @__PURE__ */ jsx(BoxIcon, {
286
+ src: mainAction.urlIcon,
287
+ sx: {
288
+ width: 18,
289
+ height: 18
290
+ }
291
+ })
292
+ }, `main_action_${index}`);
293
+ }
294
+ return /* @__PURE__ */ jsx(mainAction.component, {
295
+ description,
296
+ onClick: mainAction.onClick
297
+ }, `main_action_${index}`);
298
+ }), menuActions.length > 0 && /* @__PURE__ */ jsx(MenuActions, {
299
+ arrow: "right-top",
300
+ marginTop: "-11px",
301
+ anchorOrigin: {
302
+ vertical: "top",
303
+ horizontal: "left"
304
+ },
305
+ transformOrigin: {
306
+ vertical: "top",
307
+ horizontal: "right"
308
+ },
309
+ menuActions
310
+ })]
311
+ });
312
+ }
313
+ const Module = forwardRef((props, ref) => {
314
+ const {
315
+ children
316
+ } = props;
317
+ const {
318
+ openModal
319
+ } = useModal();
320
+ const divRef = useRef(null);
321
+ useImperativeHandle(ref, () => ({
322
+ openModal,
323
+ current: divRef.current
324
+ }));
325
+ return /* @__PURE__ */ jsxs(WrapperModule, {
326
+ id: "WrapperModule",
327
+ ref: divRef,
328
+ children: [/* @__PURE__ */ jsx(Header, {}), /* @__PURE__ */ jsx(ModuleContent, {
329
+ id: "ModuleContent",
330
+ children
331
+ })]
332
+ });
333
+ });
334
+ Module.displayName = "Module";
335
+ const ModuleLayout = forwardRef((props, ref) => {
336
+ const {
337
+ moduleId,
338
+ moduleNameField = "module_name",
339
+ initialModuleActions,
340
+ urlIcon,
341
+ children,
342
+ componentsDictionary,
343
+ breadcrumbLinks
344
+ } = props;
345
+ const moduleRef = useRef(null);
346
+ const openModal = (modalOpenProps) => {
347
+ moduleRef.current?.openModal(modalOpenProps);
348
+ };
349
+ useImperativeHandle(ref, () => ({
350
+ openModal,
351
+ current: moduleRef.current
352
+ }));
353
+ return /* @__PURE__ */ jsx(FlagsProvider, {
354
+ children: /* @__PURE__ */ jsx(ModuleDictionaryProvider, {
355
+ moduleId,
356
+ componentsDictionary,
357
+ children: /* @__PURE__ */ jsx(ModuleProvider, {
358
+ moduleId,
359
+ urlIcon,
360
+ moduleNameField,
361
+ initialModuleActions,
362
+ breadcrumbLinks,
363
+ children: /* @__PURE__ */ jsx(ModalProvider, {
364
+ children: /* @__PURE__ */ jsx(Module, {
365
+ ref: moduleRef,
366
+ children
367
+ })
368
+ })
369
+ })
370
+ })
371
+ });
372
+ });
373
+ ModuleLayout.displayName = "ModuleLayout";
374
+ function getModuleLayoutComponentsDictionary() {
375
+ return ["module_layout"].concat(getModalDialogComponentsDictionary());
376
+ }
377
+ const defaultModuleLayoutDictionary = {
378
+ module_layout: {}
379
+ };
380
+ export { ModuleContext as M, ModuleLayout as a, defaultModuleLayoutDictionary as d, getModuleLayoutComponentsDictionary as g };
@@ -0,0 +1,28 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ModuleDictionary } from '@m4l/core';
3
+ import type { MenuAction, TLink, ModalOpenOptions } from '@m4l/components';
4
+ import type { HeaderProps } from './components/Header/types';
5
+ import type { ModuleRef } from './components/ModuleContent/types';
6
+ export interface ContainerProps {
7
+ vertical: boolean;
8
+ }
9
+ export declare type MenuActionType = 'main' | 'allways' | 'normal';
10
+ export declare type ModuleLayoutRef = {
11
+ openModal: (modalOpenProps: ModalOpenOptions) => void;
12
+ current: ModuleRef | null;
13
+ };
14
+ export interface ModuleAction extends MenuAction {
15
+ visibility: MenuActionType;
16
+ tag?: any;
17
+ className?: string;
18
+ }
19
+ export interface ModuleLayoutProps extends HeaderProps {
20
+ moduleId: number;
21
+ urlIcon: string;
22
+ moduleNameField?: string;
23
+ breadcrumbLinks: TLink[];
24
+ initialModuleActions: ModuleAction[];
25
+ defaultDictionary: ModuleDictionary;
26
+ componentsDictionary: string[];
27
+ children: ReactNode;
28
+ }
@@ -0,0 +1,2 @@
1
+ export { MasterDetailLayout } from './MasterDetailLayout';
2
+ export { ModuleLayout } from './ModuleLayout';
package/dist/vendor.js ADDED
@@ -0,0 +1,35 @@
1
+ import { useTheme } from "@mui/material/styles";
2
+ import useMediaQuery from "@mui/material/useMediaQuery";
3
+ import "react";
4
+ import "@m4l/core";
5
+ import "@m4l/components";
6
+ import "./layouts/ModuleLayout/index.js";
7
+ import "./layouts/MasterDetailLayout/index.js";
8
+ import "@mui/material";
9
+ import "react/jsx-runtime";
10
+ import "./hooks/useMasterDetail/index.js";
11
+ import "./hooks/useModule/index.js";
12
+ function useResponsive(query, key, start, end) {
13
+ const theme = useTheme();
14
+ const mediaUp = useMediaQuery(theme.breakpoints.up(key));
15
+ const mediaDown = useMediaQuery(theme.breakpoints.down(key));
16
+ const mediaBetween = useMediaQuery(theme.breakpoints.between(start, end));
17
+ const mediaOnly = useMediaQuery(theme.breakpoints.only(key));
18
+ if (query === "up") {
19
+ return mediaUp;
20
+ }
21
+ if (query === "down") {
22
+ return mediaDown;
23
+ }
24
+ if (query === "between") {
25
+ return mediaBetween;
26
+ }
27
+ if (query === "only") {
28
+ return mediaOnly;
29
+ }
30
+ }
31
+ function useResponsiveDesktop() {
32
+ const isDesktop = useResponsive("up", "sm");
33
+ return isDesktop;
34
+ }
35
+ export { useResponsiveDesktop as u };
@@ -0,0 +1,3 @@
1
+ /// <reference types="vite/client" />
2
+ /// <reference types="vitest" />
3
+ /// <reference types="vitest/importMeta" />
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@m4l/layouts",
3
+ "private": false,
4
+ "version": "1.0.4",
5
+ "license": "UNLICENSED",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview",
10
+ "lint": "npx eslint src",
11
+ "lint:fix": "npm run lint -- --fix",
12
+ "prettier": "npx prettier src --check",
13
+ "prettier:fix": "npm run prettier -- --write",
14
+ "format": "npm run prettier:fix && npm run lint:fix"
15
+ },
16
+ "dependencies": {
17
+ "@m4l/components": "^0.0.4",
18
+ "react": "^17.0.0 || 18.x",
19
+ "react-dom": "^18.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "@emotion/styled": "^11.9.3",
23
+ "@testing-library/react": "^13.3.0",
24
+ "@testing-library/user-event": "^14.2.1",
25
+ "@types/node": "^17.0.40",
26
+ "@types/react": "^18.0.0",
27
+ "@types/react-dom": "^18.0.0",
28
+ "@typescript-eslint/eslint-plugin": "^5.27.1",
29
+ "@typescript-eslint/parser": "^5.27.1",
30
+ "@vitejs/plugin-react": "^1.3.0",
31
+ "eslint": "^8.17.0",
32
+ "eslint-config-prettier": "^8.5.0",
33
+ "eslint-import-resolver-alias": "^1.1.2",
34
+ "eslint-plugin-import": "^2.26.0",
35
+ "eslint-plugin-jsx-a11y": "^6.5.1",
36
+ "eslint-plugin-prettier": "^4.0.0",
37
+ "eslint-plugin-react": "^7.30.0",
38
+ "eslint-plugin-react-hooks": "^4.5.0",
39
+ "eslint-plugin-unused-imports": "^2.0.0",
40
+ "prettier": "^2.6.2",
41
+ "rollup-plugin-terser": "^7.0.2",
42
+ "typescript": "^4.6.3",
43
+ "vite": "^2.9.9",
44
+ "vite-plugin-dts": "^1.2.0",
45
+ "vite-plugin-mkcert": "^1.6.4",
46
+ "vitest": "^0.17.1"
47
+ },
48
+ "peerDependencies": {
49
+ "react": "^17.0.0 || 18.x",
50
+ "react-dom": "^18.0.0",
51
+ "@m4l/components": "^0.0.4"
52
+ },
53
+ "files": [
54
+ "dist"
55
+ ],
56
+ "main": "./dist/index.js",
57
+ "module": "./dist/index.js",
58
+ "types": "./dist/index.d.ts",
59
+ "type": "module",
60
+ "exports": {
61
+ ".": {
62
+ "import": "./dist/index.js"
63
+ }
64
+ },
65
+ "sideEffects": false,
66
+ "publishConfig": {
67
+ "access": "public"
68
+ },
69
+ "engines": {
70
+ "node": ">=12.0.0"
71
+ }
72
+ }