@compill/admin 1.0.81 → 1.0.82

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/index.cjs.js CHANGED
@@ -25,6 +25,7 @@ var hooks = require('@compill/hooks');
25
25
  var env = require('@compill/env');
26
26
  var reactQuery = require('@tanstack/react-query');
27
27
  var Image = require('next/image');
28
+ var auth = require('@compill/auth');
28
29
 
29
30
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
30
31
 
@@ -94,11 +95,14 @@ var mdiArrowLeft = "M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.
94
95
  var mdiArrowUpBoldBox = "M19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21M12,7L7,12H10V16H14V12H17L12,7Z";
95
96
  var mdiCircleSmall = "M12,10A2,2 0 0,0 10,12C10,13.11 10.9,14 12,14C13.11,14 14,13.11 14,12A2,2 0 0,0 12,10Z";
96
97
  var mdiCloudUpload = "M11 20H6.5Q4.22 20 2.61 18.43 1 16.85 1 14.58 1 12.63 2.17 11.1 3.35 9.57 5.25 9.15 5.88 6.85 7.75 5.43 9.63 4 12 4 14.93 4 16.96 6.04 19 8.07 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 17.38 21.69 18.69 20.38 20 18.5 20H13V12.85L14.6 14.4L16 13L12 9L8 13L9.4 14.4L11 12.85Z";
98
+ var mdiCog = "M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z";
97
99
  var mdiDatabaseRefreshOutline = "M6 12.45V9.64C7.47 10.47 9.61 11 12 11S16.53 10.47 18 9.64V12.03C18.17 12 18.33 12 18.5 12C19 12 19.5 12.07 20 12.18V7C20 4.79 16.42 3 12 3S4 4.79 4 7V17C4 19.21 7.59 21 12 21C12.17 21 12.33 21 12.5 21C12.24 20.37 12.09 19.7 12.03 19L12 19C8.13 19 6 17.5 6 17V14.77C7.61 15.55 9.72 16 12 16C12.17 16 12.34 16 12.5 16C12.85 15.18 13.34 14.46 13.95 13.86C13.32 13.95 12.67 14 12 14C9.58 14 7.3 13.4 6 12.45M12 5C15.87 5 18 6.5 18 7S15.87 9 12 9 6 7.5 6 7 8.13 5 12 5M18 18.5L19.77 16.73C19.32 16.28 18.69 16 18 16C16.62 16 15.5 17.12 15.5 18.5S16.62 21 18 21C18.82 21 19.54 20.61 20 20H21.71C21.12 21.47 19.68 22.5 18 22.5C15.79 22.5 14 20.71 14 18.5S15.79 14.5 18 14.5C19.11 14.5 20.11 14.95 20.83 15.67L22 14.5V18.5H18Z";
98
100
  var mdiDelete = "M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z";
101
+ var mdiDotsVertical = "M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z";
99
102
  var mdiEye = "M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z";
100
103
  var mdiEyeOff = "M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z";
101
104
  var mdiFilter = "M14,12V19.88C14.04,20.18 13.94,20.5 13.71,20.71C13.32,21.1 12.69,21.1 12.3,20.71L10.29,18.7C10.06,18.47 9.96,18.16 10,17.87V12H9.97L4.21,4.62C3.87,4.19 3.95,3.56 4.38,3.22C4.57,3.08 4.78,3 5,3V3H19V3C19.22,3 19.43,3.08 19.62,3.22C20.05,3.56 20.13,4.19 19.79,4.62L14.03,12H14Z";
105
+ var mdiLogout = "M17 7L15.59 8.41L18.17 11H8V13H18.17L15.59 15.58L17 17L22 12M4 5H12V3H4C2.9 3 2 3.9 2 5V19C2 20.1 2.9 21 4 21H12V19H4V5Z";
102
106
  var mdiOpenInNew = "M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z";
103
107
  var mdiPencil = "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z";
104
108
  var mdiPlusThick = "M20 14H14V20H10V14H4V10H10V4H14V10H20V14Z";
@@ -1777,6 +1781,10 @@ function isEqual(a, b) {
1777
1781
  return isEqualWith(a, b, noop);
1778
1782
  }
1779
1783
 
1784
+ function capitalize(str) {
1785
+ return (str.charAt(0).toUpperCase() + str.slice(1).toLowerCase());
1786
+ }
1787
+
1780
1788
  function TableFilters({
1781
1789
  form: form$1,
1782
1790
  initialValues,
@@ -2873,7 +2881,7 @@ function MenuButton(_a) {
2873
2881
  }));
2874
2882
  }
2875
2883
 
2876
- function MenuItem(_a) {
2884
+ function MenuItem$1(_a) {
2877
2885
  var {
2878
2886
  icon,
2879
2887
  path,
@@ -2900,7 +2908,7 @@ function MenuItem(_a) {
2900
2908
  }, props)), match && jsxRuntime.jsx(SelectedIndicator, {
2901
2909
  darkMode: darkMode
2902
2910
  })]
2903
- }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((item, index) => jsxRuntime.jsx(MenuItem, {
2911
+ }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((item, index) => jsxRuntime.jsx(MenuItem$1, {
2904
2912
  icon: item.icon,
2905
2913
  path: item.path,
2906
2914
  depth: (depth !== null && depth !== void 0 ? depth : 0) + 1,
@@ -2961,7 +2969,7 @@ function Menu(_a) {
2961
2969
  useNextRouter
2962
2970
  } = _a,
2963
2971
  props = __rest(_a, ["darkMode", "config", "useNextRouter"]);
2964
- const Comp = useNextRouter ? NextMenuItem : MenuItem;
2972
+ const Comp = useNextRouter ? NextMenuItem : MenuItem$1;
2965
2973
  return jsxRuntime.jsx("ul", Object.assign({}, props, {
2966
2974
  children: config.map((item, index) => {
2967
2975
  if (item.type == "divider") return jsxRuntime.jsx(Divider, {
@@ -2996,17 +3004,160 @@ function Divider({
2996
3004
  });
2997
3005
  }
2998
3006
 
3007
+ function UserBlock({
3008
+ color,
3009
+ darkMode,
3010
+ menuConfig,
3011
+ path
3012
+ }) {
3013
+ var _a, _b, _c, _d;
3014
+ const {
3015
+ isLoading,
3016
+ user
3017
+ } = auth.useSessionUser();
3018
+ const navigate = reactRouterDom.useNavigate();
3019
+ const handleClick = React__default["default"].useCallback(() => navigate(path), [navigate, path]);
3020
+ if (isLoading) return null;
3021
+ return jsxRuntime.jsxs("div", {
3022
+ dflex: true,
3023
+ alignItems: "center",
3024
+ border: "0.5",
3025
+ borderColor: `${color}-${darkMode ? "800" : "200"}`,
3026
+ ps: "3",
3027
+ py: "1.5",
3028
+ textSize: "md",
3029
+ rounded: "lg",
3030
+ hover_bgColor: `${color}-${darkMode ? "800" : "200"}`,
3031
+ cursor: "pointer",
3032
+ textColor: darkMode ? "white" : "slate-800",
3033
+ onClick: handleClick,
3034
+ children: [jsxRuntime.jsx(ui.Avatar, {
3035
+ size: "sm",
3036
+ src: (_b = (_a = user === null || user === void 0 ? void 0 : user.media) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : "",
3037
+ name: `${user === null || user === void 0 ? void 0 : user.firstname} ${user === null || user === void 0 ? void 0 : user.lastname}`
3038
+ }), jsxRuntime.jsx("span", {
3039
+ flexGrow: true,
3040
+ ms: "2",
3041
+ children: `${capitalize((_d = (_c = user === null || user === void 0 ? void 0 : user.firstname) !== null && _c !== void 0 ? _c : user === null || user === void 0 ? void 0 : user.lastname) !== null && _d !== void 0 ? _d : "Jonathan")}`
3042
+ }), jsxRuntime.jsx(ui.IconButton, {
3043
+ variant: "borderless",
3044
+ corners: "pill",
3045
+ scheme: "dark",
3046
+ textColor: darkMode ? "white" : "slate-800",
3047
+ hover_textColor: darkMode ? "white" : "slate-800",
3048
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`,
3049
+ icon: mdiCog,
3050
+ onClick: handleClick
3051
+ }), jsxRuntime.jsx(OverflowMenu, {
3052
+ color: color,
3053
+ darkMode: darkMode,
3054
+ menuConfig: menuConfig
3055
+ })]
3056
+ });
3057
+ }
3058
+ function OverflowMenu({
3059
+ color,
3060
+ darkMode,
3061
+ menuConfig
3062
+ }) {
3063
+ const [showPopup, setShowPopup] = React__default["default"].useState(false);
3064
+ const navigate = reactRouterDom.useNavigate();
3065
+ const logout = auth.useSessionLogout(false);
3066
+ return jsxRuntime.jsx(jsxRuntime.Fragment, {
3067
+ children: jsxRuntime.jsxs(ui.Popup, {
3068
+ show: showPopup,
3069
+ position: "relative",
3070
+ side: "bottom-end",
3071
+ onClick: e => {
3072
+ e.preventDefault();
3073
+ e.stopPropagation();
3074
+ setShowPopup(show => !show);
3075
+ },
3076
+ onHide: () => setShowPopup(false),
3077
+ children: [jsxRuntime.jsx(ui.IconButton, {
3078
+ icon: mdiDotsVertical,
3079
+ variant: "borderless",
3080
+ corners: "pill",
3081
+ scheme: "dark",
3082
+ textColor: darkMode ? "white" : "slate-800",
3083
+ hover_textColor: darkMode ? "white" : "slate-800",
3084
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`
3085
+ }), jsxRuntime.jsxs("div", {
3086
+ bgColor: "white",
3087
+ rounded: "sm",
3088
+ overflow: "hidden",
3089
+ shadow: true,
3090
+ mt: "1",
3091
+ border: "px",
3092
+ borderColor: "gray-200",
3093
+ divideColor: "gray-200",
3094
+ divideY: "px",
3095
+ minW: "40",
3096
+ children: [menuConfig && menuConfig.length > 0 && menuConfig.map((item, index) => {
3097
+ if (item.type == "item") {
3098
+ return jsxRuntime.jsx(MenuItem, {
3099
+ icon: item.icon,
3100
+ onClick: () => navigate(item.path),
3101
+ children: item.label
3102
+ }, index);
3103
+ }
3104
+ return null;
3105
+ }), jsxRuntime.jsx(MenuItem, {
3106
+ icon: mdiLogout,
3107
+ onClick: logout,
3108
+ children: "Logout"
3109
+ })]
3110
+ })]
3111
+ })
3112
+ });
3113
+ }
3114
+ function MenuItem(_a) {
3115
+ var {
3116
+ icon,
3117
+ onClick,
3118
+ children
3119
+ } = _a,
3120
+ props = __rest(_a, ["icon", "onClick", "children"]);
3121
+ const handleClick = React__default["default"].useCallback(e => {
3122
+ e.preventDefault();
3123
+ e.stopPropagation();
3124
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
3125
+ }, []);
3126
+ return jsxRuntime.jsxs(ui.Button, Object.assign({
3127
+ variant: "borderless",
3128
+ scheme: "dark",
3129
+ size: "sm",
3130
+ alignItems: "center",
3131
+ dflex: true,
3132
+ gap: "2",
3133
+ px: "2",
3134
+ py: "1.5",
3135
+ w: "full",
3136
+ onClick: handleClick,
3137
+ textColor: "slate-700"
3138
+ }, props, {
3139
+ children: [icon && jsxRuntime.jsx(ui.Icon, {
3140
+ path: icon,
3141
+ size: "md"
3142
+ }), children]
3143
+ }));
3144
+ }
3145
+
2999
3146
  function Sidebar(_a) {
3000
3147
  var {
3001
3148
  show,
3002
3149
  logo,
3003
3150
  title,
3004
3151
  menuConfig,
3152
+ userMenuConfig,
3153
+ userSettingsPath,
3005
3154
  color,
3006
3155
  darkMode
3007
3156
  } = _a,
3008
- props = __rest(_a, ["show", "logo", "title", "menuConfig", "color", "darkMode"]);
3157
+ props = __rest(_a, ["show", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath", "color", "darkMode"]);
3009
3158
  return jsxRuntime.jsxs("div", Object.assign({
3159
+ dflex: true,
3160
+ flexCol: true,
3010
3161
  w: "64",
3011
3162
  minH: "screen",
3012
3163
  p: "0",
@@ -3034,6 +3185,14 @@ function Sidebar(_a) {
3034
3185
  p: "4",
3035
3186
  darkMode: darkMode,
3036
3187
  config: menuConfig
3188
+ }), jsxRuntime.jsx("div", {
3189
+ p: "2",
3190
+ children: jsxRuntime.jsx(UserBlock, {
3191
+ darkMode: darkMode,
3192
+ color: color,
3193
+ menuConfig: userMenuConfig,
3194
+ path: userSettingsPath
3195
+ })
3037
3196
  })]
3038
3197
  }));
3039
3198
  }
@@ -3062,9 +3221,11 @@ function AdminLayout(_a) {
3062
3221
  darkMode,
3063
3222
  logo,
3064
3223
  title,
3065
- menuConfig
3224
+ menuConfig,
3225
+ userMenuConfig,
3226
+ userSettingsPath
3066
3227
  } = _a,
3067
- props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig"]);
3228
+ props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath"]);
3068
3229
  return jsxRuntime.jsxs("div", Object.assign({
3069
3230
  w: "full",
3070
3231
  h: "screen",
@@ -3077,7 +3238,9 @@ function AdminLayout(_a) {
3077
3238
  darkMode: darkMode,
3078
3239
  logo: logo,
3079
3240
  title: title,
3080
- menuConfig: menuConfig
3241
+ menuConfig: menuConfig,
3242
+ userMenuConfig: userMenuConfig,
3243
+ userSettingsPath: userSettingsPath
3081
3244
  }), jsxRuntime.jsx("div", {
3082
3245
  w: "screen",
3083
3246
  py: "2",
@@ -3095,7 +3258,9 @@ function LeftPanel({
3095
3258
  darkMode,
3096
3259
  logo,
3097
3260
  title,
3098
- menuConfig
3261
+ menuConfig,
3262
+ userMenuConfig,
3263
+ userSettingsPath
3099
3264
  }) {
3100
3265
  const [isOpen, __, toggle] = hooks.useBoolean(true);
3101
3266
  useHotkeys('ctrl+t', () => toggle(), [toggle]);
@@ -3110,7 +3275,9 @@ function LeftPanel({
3110
3275
  darkMode: darkMode,
3111
3276
  logo: logo,
3112
3277
  title: title,
3113
- menuConfig: menuConfig
3278
+ menuConfig: menuConfig,
3279
+ userMenuConfig: userMenuConfig,
3280
+ userSettingsPath: userSettingsPath
3114
3281
  }), jsxRuntime.jsx(ui.IconButton, {
3115
3282
  icon: mdiArrowLeft,
3116
3283
  transition: "all",
package/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from '@soperio/jsx-runtime';
2
- import { Icon, Button, IconButton, Container, Tile, Popover, Collapse, Modal, Checkbox, Badge } from '@valerya/ui';
2
+ import { Icon, Button, IconButton, Container, Tile, Popover, Collapse, Modal, Avatar, Popup, Checkbox, Badge } from '@valerya/ui';
3
3
  import Link from 'next/link';
4
4
  import React, { useRef, useCallback, useContext as useContext$2, useLayoutEffect, useEffect, createContext } from 'react';
5
5
  import { INVALIDATE_API, API } from '@compill/admin-api';
@@ -21,6 +21,7 @@ import { useOpenLink, useBoolean } from '@compill/hooks';
21
21
  import { AppEnv } from '@compill/env';
22
22
  import { useQueryClient } from '@tanstack/react-query';
23
23
  import Image from 'next/image';
24
+ import { useSessionUser, useSessionLogout } from '@compill/auth';
24
25
 
25
26
  /******************************************************************************
26
27
  Copyright (c) Microsoft Corporation.
@@ -84,11 +85,14 @@ var mdiArrowLeft = "M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.
84
85
  var mdiArrowUpBoldBox = "M19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21M12,7L7,12H10V16H14V12H17L12,7Z";
85
86
  var mdiCircleSmall = "M12,10A2,2 0 0,0 10,12C10,13.11 10.9,14 12,14C13.11,14 14,13.11 14,12A2,2 0 0,0 12,10Z";
86
87
  var mdiCloudUpload = "M11 20H6.5Q4.22 20 2.61 18.43 1 16.85 1 14.58 1 12.63 2.17 11.1 3.35 9.57 5.25 9.15 5.88 6.85 7.75 5.43 9.63 4 12 4 14.93 4 16.96 6.04 19 8.07 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 17.38 21.69 18.69 20.38 20 18.5 20H13V12.85L14.6 14.4L16 13L12 9L8 13L9.4 14.4L11 12.85Z";
88
+ var mdiCog = "M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z";
87
89
  var mdiDatabaseRefreshOutline = "M6 12.45V9.64C7.47 10.47 9.61 11 12 11S16.53 10.47 18 9.64V12.03C18.17 12 18.33 12 18.5 12C19 12 19.5 12.07 20 12.18V7C20 4.79 16.42 3 12 3S4 4.79 4 7V17C4 19.21 7.59 21 12 21C12.17 21 12.33 21 12.5 21C12.24 20.37 12.09 19.7 12.03 19L12 19C8.13 19 6 17.5 6 17V14.77C7.61 15.55 9.72 16 12 16C12.17 16 12.34 16 12.5 16C12.85 15.18 13.34 14.46 13.95 13.86C13.32 13.95 12.67 14 12 14C9.58 14 7.3 13.4 6 12.45M12 5C15.87 5 18 6.5 18 7S15.87 9 12 9 6 7.5 6 7 8.13 5 12 5M18 18.5L19.77 16.73C19.32 16.28 18.69 16 18 16C16.62 16 15.5 17.12 15.5 18.5S16.62 21 18 21C18.82 21 19.54 20.61 20 20H21.71C21.12 21.47 19.68 22.5 18 22.5C15.79 22.5 14 20.71 14 18.5S15.79 14.5 18 14.5C19.11 14.5 20.11 14.95 20.83 15.67L22 14.5V18.5H18Z";
88
90
  var mdiDelete = "M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z";
91
+ var mdiDotsVertical = "M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z";
89
92
  var mdiEye = "M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z";
90
93
  var mdiEyeOff = "M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z";
91
94
  var mdiFilter = "M14,12V19.88C14.04,20.18 13.94,20.5 13.71,20.71C13.32,21.1 12.69,21.1 12.3,20.71L10.29,18.7C10.06,18.47 9.96,18.16 10,17.87V12H9.97L4.21,4.62C3.87,4.19 3.95,3.56 4.38,3.22C4.57,3.08 4.78,3 5,3V3H19V3C19.22,3 19.43,3.08 19.62,3.22C20.05,3.56 20.13,4.19 19.79,4.62L14.03,12H14Z";
95
+ var mdiLogout = "M17 7L15.59 8.41L18.17 11H8V13H18.17L15.59 15.58L17 17L22 12M4 5H12V3H4C2.9 3 2 3.9 2 5V19C2 20.1 2.9 21 4 21H12V19H4V5Z";
92
96
  var mdiOpenInNew = "M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z";
93
97
  var mdiPencil = "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z";
94
98
  var mdiPlusThick = "M20 14H14V20H10V14H4V10H10V4H14V10H20V14Z";
@@ -1767,6 +1771,10 @@ function isEqual(a, b) {
1767
1771
  return isEqualWith(a, b, noop);
1768
1772
  }
1769
1773
 
1774
+ function capitalize(str) {
1775
+ return (str.charAt(0).toUpperCase() + str.slice(1).toLowerCase());
1776
+ }
1777
+
1770
1778
  function TableFilters({
1771
1779
  form,
1772
1780
  initialValues,
@@ -2863,7 +2871,7 @@ function MenuButton(_a) {
2863
2871
  }));
2864
2872
  }
2865
2873
 
2866
- function MenuItem(_a) {
2874
+ function MenuItem$1(_a) {
2867
2875
  var {
2868
2876
  icon,
2869
2877
  path,
@@ -2890,7 +2898,7 @@ function MenuItem(_a) {
2890
2898
  }, props)), match && jsx(SelectedIndicator, {
2891
2899
  darkMode: darkMode
2892
2900
  })]
2893
- }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((item, index) => jsx(MenuItem, {
2901
+ }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((item, index) => jsx(MenuItem$1, {
2894
2902
  icon: item.icon,
2895
2903
  path: item.path,
2896
2904
  depth: (depth !== null && depth !== void 0 ? depth : 0) + 1,
@@ -2951,7 +2959,7 @@ function Menu(_a) {
2951
2959
  useNextRouter
2952
2960
  } = _a,
2953
2961
  props = __rest(_a, ["darkMode", "config", "useNextRouter"]);
2954
- const Comp = useNextRouter ? NextMenuItem : MenuItem;
2962
+ const Comp = useNextRouter ? NextMenuItem : MenuItem$1;
2955
2963
  return jsx("ul", Object.assign({}, props, {
2956
2964
  children: config.map((item, index) => {
2957
2965
  if (item.type == "divider") return jsx(Divider, {
@@ -2986,17 +2994,160 @@ function Divider({
2986
2994
  });
2987
2995
  }
2988
2996
 
2997
+ function UserBlock({
2998
+ color,
2999
+ darkMode,
3000
+ menuConfig,
3001
+ path
3002
+ }) {
3003
+ var _a, _b, _c, _d;
3004
+ const {
3005
+ isLoading,
3006
+ user
3007
+ } = useSessionUser();
3008
+ const navigate = useNavigate();
3009
+ const handleClick = React.useCallback(() => navigate(path), [navigate, path]);
3010
+ if (isLoading) return null;
3011
+ return jsxs("div", {
3012
+ dflex: true,
3013
+ alignItems: "center",
3014
+ border: "0.5",
3015
+ borderColor: `${color}-${darkMode ? "800" : "200"}`,
3016
+ ps: "3",
3017
+ py: "1.5",
3018
+ textSize: "md",
3019
+ rounded: "lg",
3020
+ hover_bgColor: `${color}-${darkMode ? "800" : "200"}`,
3021
+ cursor: "pointer",
3022
+ textColor: darkMode ? "white" : "slate-800",
3023
+ onClick: handleClick,
3024
+ children: [jsx(Avatar, {
3025
+ size: "sm",
3026
+ src: (_b = (_a = user === null || user === void 0 ? void 0 : user.media) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : "",
3027
+ name: `${user === null || user === void 0 ? void 0 : user.firstname} ${user === null || user === void 0 ? void 0 : user.lastname}`
3028
+ }), jsx("span", {
3029
+ flexGrow: true,
3030
+ ms: "2",
3031
+ children: `${capitalize((_d = (_c = user === null || user === void 0 ? void 0 : user.firstname) !== null && _c !== void 0 ? _c : user === null || user === void 0 ? void 0 : user.lastname) !== null && _d !== void 0 ? _d : "Jonathan")}`
3032
+ }), jsx(IconButton, {
3033
+ variant: "borderless",
3034
+ corners: "pill",
3035
+ scheme: "dark",
3036
+ textColor: darkMode ? "white" : "slate-800",
3037
+ hover_textColor: darkMode ? "white" : "slate-800",
3038
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`,
3039
+ icon: mdiCog,
3040
+ onClick: handleClick
3041
+ }), jsx(OverflowMenu, {
3042
+ color: color,
3043
+ darkMode: darkMode,
3044
+ menuConfig: menuConfig
3045
+ })]
3046
+ });
3047
+ }
3048
+ function OverflowMenu({
3049
+ color,
3050
+ darkMode,
3051
+ menuConfig
3052
+ }) {
3053
+ const [showPopup, setShowPopup] = React.useState(false);
3054
+ const navigate = useNavigate();
3055
+ const logout = useSessionLogout(false);
3056
+ return jsx(Fragment, {
3057
+ children: jsxs(Popup, {
3058
+ show: showPopup,
3059
+ position: "relative",
3060
+ side: "bottom-end",
3061
+ onClick: e => {
3062
+ e.preventDefault();
3063
+ e.stopPropagation();
3064
+ setShowPopup(show => !show);
3065
+ },
3066
+ onHide: () => setShowPopup(false),
3067
+ children: [jsx(IconButton, {
3068
+ icon: mdiDotsVertical,
3069
+ variant: "borderless",
3070
+ corners: "pill",
3071
+ scheme: "dark",
3072
+ textColor: darkMode ? "white" : "slate-800",
3073
+ hover_textColor: darkMode ? "white" : "slate-800",
3074
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`
3075
+ }), jsxs("div", {
3076
+ bgColor: "white",
3077
+ rounded: "sm",
3078
+ overflow: "hidden",
3079
+ shadow: true,
3080
+ mt: "1",
3081
+ border: "px",
3082
+ borderColor: "gray-200",
3083
+ divideColor: "gray-200",
3084
+ divideY: "px",
3085
+ minW: "40",
3086
+ children: [menuConfig && menuConfig.length > 0 && menuConfig.map((item, index) => {
3087
+ if (item.type == "item") {
3088
+ return jsx(MenuItem, {
3089
+ icon: item.icon,
3090
+ onClick: () => navigate(item.path),
3091
+ children: item.label
3092
+ }, index);
3093
+ }
3094
+ return null;
3095
+ }), jsx(MenuItem, {
3096
+ icon: mdiLogout,
3097
+ onClick: logout,
3098
+ children: "Logout"
3099
+ })]
3100
+ })]
3101
+ })
3102
+ });
3103
+ }
3104
+ function MenuItem(_a) {
3105
+ var {
3106
+ icon,
3107
+ onClick,
3108
+ children
3109
+ } = _a,
3110
+ props = __rest(_a, ["icon", "onClick", "children"]);
3111
+ const handleClick = React.useCallback(e => {
3112
+ e.preventDefault();
3113
+ e.stopPropagation();
3114
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
3115
+ }, []);
3116
+ return jsxs(Button, Object.assign({
3117
+ variant: "borderless",
3118
+ scheme: "dark",
3119
+ size: "sm",
3120
+ alignItems: "center",
3121
+ dflex: true,
3122
+ gap: "2",
3123
+ px: "2",
3124
+ py: "1.5",
3125
+ w: "full",
3126
+ onClick: handleClick,
3127
+ textColor: "slate-700"
3128
+ }, props, {
3129
+ children: [icon && jsx(Icon, {
3130
+ path: icon,
3131
+ size: "md"
3132
+ }), children]
3133
+ }));
3134
+ }
3135
+
2989
3136
  function Sidebar(_a) {
2990
3137
  var {
2991
3138
  show,
2992
3139
  logo,
2993
3140
  title,
2994
3141
  menuConfig,
3142
+ userMenuConfig,
3143
+ userSettingsPath,
2995
3144
  color,
2996
3145
  darkMode
2997
3146
  } = _a,
2998
- props = __rest(_a, ["show", "logo", "title", "menuConfig", "color", "darkMode"]);
3147
+ props = __rest(_a, ["show", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath", "color", "darkMode"]);
2999
3148
  return jsxs("div", Object.assign({
3149
+ dflex: true,
3150
+ flexCol: true,
3000
3151
  w: "64",
3001
3152
  minH: "screen",
3002
3153
  p: "0",
@@ -3024,6 +3175,14 @@ function Sidebar(_a) {
3024
3175
  p: "4",
3025
3176
  darkMode: darkMode,
3026
3177
  config: menuConfig
3178
+ }), jsx("div", {
3179
+ p: "2",
3180
+ children: jsx(UserBlock, {
3181
+ darkMode: darkMode,
3182
+ color: color,
3183
+ menuConfig: userMenuConfig,
3184
+ path: userSettingsPath
3185
+ })
3027
3186
  })]
3028
3187
  }));
3029
3188
  }
@@ -3052,9 +3211,11 @@ function AdminLayout(_a) {
3052
3211
  darkMode,
3053
3212
  logo,
3054
3213
  title,
3055
- menuConfig
3214
+ menuConfig,
3215
+ userMenuConfig,
3216
+ userSettingsPath
3056
3217
  } = _a,
3057
- props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig"]);
3218
+ props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath"]);
3058
3219
  return jsxs("div", Object.assign({
3059
3220
  w: "full",
3060
3221
  h: "screen",
@@ -3067,7 +3228,9 @@ function AdminLayout(_a) {
3067
3228
  darkMode: darkMode,
3068
3229
  logo: logo,
3069
3230
  title: title,
3070
- menuConfig: menuConfig
3231
+ menuConfig: menuConfig,
3232
+ userMenuConfig: userMenuConfig,
3233
+ userSettingsPath: userSettingsPath
3071
3234
  }), jsx("div", {
3072
3235
  w: "screen",
3073
3236
  py: "2",
@@ -3085,7 +3248,9 @@ function LeftPanel({
3085
3248
  darkMode,
3086
3249
  logo,
3087
3250
  title,
3088
- menuConfig
3251
+ menuConfig,
3252
+ userMenuConfig,
3253
+ userSettingsPath
3089
3254
  }) {
3090
3255
  const [isOpen, __, toggle] = useBoolean(true);
3091
3256
  useHotkeys('ctrl+t', () => toggle(), [toggle]);
@@ -3100,7 +3265,9 @@ function LeftPanel({
3100
3265
  darkMode: darkMode,
3101
3266
  logo: logo,
3102
3267
  title: title,
3103
- menuConfig: menuConfig
3268
+ menuConfig: menuConfig,
3269
+ userMenuConfig: userMenuConfig,
3270
+ userSettingsPath: userSettingsPath
3104
3271
  }), jsx(IconButton, {
3105
3272
  icon: mdiArrowLeft,
3106
3273
  transition: "all",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compill/admin",
3
- "version": "1.0.81",
3
+ "version": "1.0.82",
4
4
  "module": "./index.esm.js",
5
5
  "main": "./index.cjs.js"
6
6
  }
@@ -7,6 +7,8 @@ interface LayoutProps extends SoperioComponent, ParentComponent {
7
7
  logo?: React.ReactNode;
8
8
  title?: string;
9
9
  menuConfig: MenuConfig;
10
+ userMenuConfig?: MenuConfig;
11
+ userSettingsPath: string;
10
12
  }
11
- export declare function AdminLayout({ color, darkMode, logo, title, menuConfig, ...props }: LayoutProps): JSX.Element;
13
+ export declare function AdminLayout({ color, darkMode, logo, title, menuConfig, userMenuConfig, userSettingsPath, ...props }: LayoutProps): JSX.Element;
12
14
  export {};
@@ -8,8 +8,10 @@ interface SidebarProps extends SoperioComponent, ParentComponent {
8
8
  logo?: React.ReactNode;
9
9
  title?: string;
10
10
  menuConfig: MenuConfig;
11
+ userMenuConfig?: MenuConfig;
12
+ userSettingsPath: string;
11
13
  }
12
- export declare function Sidebar({ show, logo, title, menuConfig, color, darkMode, ...props }: SidebarProps): JSX.Element;
14
+ export declare function Sidebar({ show, logo, title, menuConfig, userMenuConfig, userSettingsPath, color, darkMode, ...props }: SidebarProps): JSX.Element;
13
15
  interface LogoProps extends SoperioComponent, ParentComponent {
14
16
  width: number;
15
17
  height: number;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { MenuConfig } from "@compill/admin";
3
+ interface UserBlockProps {
4
+ color: string;
5
+ darkMode?: boolean;
6
+ menuConfig?: MenuConfig;
7
+ path: string;
8
+ }
9
+ export declare function UserBlock({ color, darkMode, menuConfig, path }: UserBlockProps): JSX.Element | null;
10
+ export {};