@compill/admin 1.0.81 → 1.0.83

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,18 +3004,162 @@ 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({
3010
- w: "64",
3159
+ dflex: true,
3160
+ flexCol: true,
3161
+ w: "full",
3162
+ md_w: "64",
3011
3163
  minH: "screen",
3012
3164
  p: "0",
3013
3165
  textColor: darkMode ? "white" : "slate-800"
@@ -3034,6 +3186,14 @@ function Sidebar(_a) {
3034
3186
  p: "4",
3035
3187
  darkMode: darkMode,
3036
3188
  config: menuConfig
3189
+ }), jsxRuntime.jsx("div", {
3190
+ p: "2",
3191
+ children: jsxRuntime.jsx(UserBlock, {
3192
+ darkMode: darkMode,
3193
+ color: color,
3194
+ menuConfig: userMenuConfig,
3195
+ path: userSettingsPath
3196
+ })
3037
3197
  })]
3038
3198
  }));
3039
3199
  }
@@ -3062,9 +3222,11 @@ function AdminLayout(_a) {
3062
3222
  darkMode,
3063
3223
  logo,
3064
3224
  title,
3065
- menuConfig
3225
+ menuConfig,
3226
+ userMenuConfig,
3227
+ userSettingsPath
3066
3228
  } = _a,
3067
- props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig"]);
3229
+ props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath"]);
3068
3230
  return jsxRuntime.jsxs("div", Object.assign({
3069
3231
  w: "full",
3070
3232
  h: "screen",
@@ -3077,7 +3239,9 @@ function AdminLayout(_a) {
3077
3239
  darkMode: darkMode,
3078
3240
  logo: logo,
3079
3241
  title: title,
3080
- menuConfig: menuConfig
3242
+ menuConfig: menuConfig,
3243
+ userMenuConfig: userMenuConfig,
3244
+ userSettingsPath: userSettingsPath
3081
3245
  }), jsxRuntime.jsx("div", {
3082
3246
  w: "screen",
3083
3247
  py: "2",
@@ -3095,7 +3259,9 @@ function LeftPanel({
3095
3259
  darkMode,
3096
3260
  logo,
3097
3261
  title,
3098
- menuConfig
3262
+ menuConfig,
3263
+ userMenuConfig,
3264
+ userSettingsPath
3099
3265
  }) {
3100
3266
  const [isOpen, __, toggle] = hooks.useBoolean(true);
3101
3267
  useHotkeys('ctrl+t', () => toggle(), [toggle]);
@@ -3110,7 +3276,9 @@ function LeftPanel({
3110
3276
  darkMode: darkMode,
3111
3277
  logo: logo,
3112
3278
  title: title,
3113
- menuConfig: menuConfig
3279
+ menuConfig: menuConfig,
3280
+ userMenuConfig: userMenuConfig,
3281
+ userSettingsPath: userSettingsPath
3114
3282
  }), jsxRuntime.jsx(ui.IconButton, {
3115
3283
  icon: mdiArrowLeft,
3116
3284
  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,18 +2994,162 @@ 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({
3000
- w: "64",
3149
+ dflex: true,
3150
+ flexCol: true,
3151
+ w: "full",
3152
+ md_w: "64",
3001
3153
  minH: "screen",
3002
3154
  p: "0",
3003
3155
  textColor: darkMode ? "white" : "slate-800"
@@ -3024,6 +3176,14 @@ function Sidebar(_a) {
3024
3176
  p: "4",
3025
3177
  darkMode: darkMode,
3026
3178
  config: menuConfig
3179
+ }), jsx("div", {
3180
+ p: "2",
3181
+ children: jsx(UserBlock, {
3182
+ darkMode: darkMode,
3183
+ color: color,
3184
+ menuConfig: userMenuConfig,
3185
+ path: userSettingsPath
3186
+ })
3027
3187
  })]
3028
3188
  }));
3029
3189
  }
@@ -3052,9 +3212,11 @@ function AdminLayout(_a) {
3052
3212
  darkMode,
3053
3213
  logo,
3054
3214
  title,
3055
- menuConfig
3215
+ menuConfig,
3216
+ userMenuConfig,
3217
+ userSettingsPath
3056
3218
  } = _a,
3057
- props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig"]);
3219
+ props = __rest(_a, ["color", "darkMode", "logo", "title", "menuConfig", "userMenuConfig", "userSettingsPath"]);
3058
3220
  return jsxs("div", Object.assign({
3059
3221
  w: "full",
3060
3222
  h: "screen",
@@ -3067,7 +3229,9 @@ function AdminLayout(_a) {
3067
3229
  darkMode: darkMode,
3068
3230
  logo: logo,
3069
3231
  title: title,
3070
- menuConfig: menuConfig
3232
+ menuConfig: menuConfig,
3233
+ userMenuConfig: userMenuConfig,
3234
+ userSettingsPath: userSettingsPath
3071
3235
  }), jsx("div", {
3072
3236
  w: "screen",
3073
3237
  py: "2",
@@ -3085,7 +3249,9 @@ function LeftPanel({
3085
3249
  darkMode,
3086
3250
  logo,
3087
3251
  title,
3088
- menuConfig
3252
+ menuConfig,
3253
+ userMenuConfig,
3254
+ userSettingsPath
3089
3255
  }) {
3090
3256
  const [isOpen, __, toggle] = useBoolean(true);
3091
3257
  useHotkeys('ctrl+t', () => toggle(), [toggle]);
@@ -3100,7 +3266,9 @@ function LeftPanel({
3100
3266
  darkMode: darkMode,
3101
3267
  logo: logo,
3102
3268
  title: title,
3103
- menuConfig: menuConfig
3269
+ menuConfig: menuConfig,
3270
+ userMenuConfig: userMenuConfig,
3271
+ userSettingsPath: userSettingsPath
3104
3272
  }), jsx(IconButton, {
3105
3273
  icon: mdiArrowLeft,
3106
3274
  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.83",
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 {};