@dashadmin/dash-admin 1.3.45 → 1.3.47

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 (43) hide show
  1. package/dist/components/i18n/BridgedLocalesMenuButton.js +1 -2
  2. package/dist/components/menu/DarkToggleMode.js +1 -1
  3. package/dist/components/subscription/PlanPricesSettings.js +4 -2
  4. package/dist/components/tenancy/GlobalTenantWrapper.js +64 -0
  5. package/dist/components/tenancy/TenantSwitcher.js +389 -0
  6. package/dist/contexts/com/components/EchoNotificationsCenter.js +40 -0
  7. package/dist/default-theme/menu/AppMenuComponents/expanded/SidebarItem.js +1 -0
  8. package/dist/index.js +60 -40
  9. package/dist/pages/Profile.js +32 -38
  10. package/dist/providers/i18n/en.js +33 -0
  11. package/dist/providers/i18n/es.js +33 -0
  12. package/dist/resources/User/components/AvatarUploadField.js +61 -0
  13. package/dist/resources/User/components/PasswordFields.js +67 -0
  14. package/dist/resources/User/getProfileMenu.js +36 -0
  15. package/dist/resources/User/profileResource.js +33 -0
  16. package/dist/resources/User/userLayout.js +58 -0
  17. package/dist/resources/User/userResource.js +90 -0
  18. package/dist/resources/User/userSchema.js +206 -0
  19. package/dist/resources/User/usersFilters.js +22 -0
  20. package/dist/systemResources.js +30 -19
  21. package/package.json +1 -1
  22. package/src/components/i18n/BridgedLocalesMenuButton.tsx +1 -2
  23. package/src/components/menu/DarkToggleMode.tsx +1 -1
  24. package/src/components/subscription/PlanPricesSettings.tsx +2 -2
  25. package/src/components/tenancy/GlobalTenantWrapper.tsx +84 -0
  26. package/src/components/tenancy/TenantSwitcher.tsx +485 -0
  27. package/src/contexts/com/components/EchoNotificationsCenter.tsx +65 -0
  28. package/src/default-theme/menu/AppMaterialMenu.tsx +1 -1
  29. package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +1 -0
  30. package/src/default-theme/menu/SidebarActions.tsx +1 -1
  31. package/src/index.tsx +15 -0
  32. package/src/pages/Profile.tsx +69 -107
  33. package/src/providers/i18n/en.ts +33 -0
  34. package/src/providers/i18n/es.ts +33 -0
  35. package/src/resources/User/components/AvatarUploadField.tsx +57 -0
  36. package/src/resources/User/components/PasswordFields.tsx +73 -0
  37. package/src/resources/User/getProfileMenu.ts +57 -0
  38. package/src/resources/User/profileResource.tsx +51 -0
  39. package/src/resources/User/userLayout.tsx +62 -0
  40. package/src/resources/User/userResource.tsx +111 -0
  41. package/src/resources/User/userSchema.tsx +213 -0
  42. package/src/resources/User/usersFilters.tsx +21 -0
  43. package/src/systemResources.tsx +31 -20
@@ -0,0 +1,62 @@
1
+ import { Box, Card, Grid } from '@mui/material';
2
+
3
+ const userLayout = (render) => {
4
+ return (
5
+ <Grid container spacing={1}>
6
+ <Grid size={{ xs: 12, md: 4 }}>
7
+ <Grid container>
8
+ <Grid size={12}>
9
+ <Card sx={{ mb: 1 }} className='dash-widget'>
10
+ <Box
11
+ sx={{ p: 1 }}
12
+ style={{ display: 'flex', alignItems: 'center' }}
13
+ >
14
+ <span className='card-title'>Avatar</span>
15
+ </Box>
16
+ <Box sx={{ p: 1 }}>{render('Avatar')}</Box>
17
+ </Card>
18
+ </Grid>
19
+ <Grid size={12}>
20
+ <Card sx={{ mb: 1 }} className='dash-widget'>
21
+ <Box
22
+ sx={{ p: 1 }}
23
+ style={{ display: 'flex', alignItems: 'center' }}
24
+ >
25
+ <span className='card-title'>Credenciales</span>
26
+ </Box>
27
+ <Box sx={{ p: 1 }}>{render('Credenciales')}</Box>
28
+ </Card>
29
+ </Grid>
30
+ </Grid>
31
+ </Grid>
32
+ <Grid size={{ xs: 12, md: 8 }}>
33
+ <Grid container >
34
+ <Grid size={12}>
35
+ <Card sx={{ mb: 1 }} className='dash-widget'>
36
+ <Box
37
+ sx={{ p: 1 }}
38
+ style={{ display: 'flex', alignItems: 'center' }}
39
+ >
40
+ <span className='card-title'>Datos del usuario</span>
41
+ </Box>
42
+ <Box sx={{ p: 1 }}>{render('Datos del usuario')}</Box>
43
+ </Card>
44
+ </Grid>
45
+ <Grid size={12}>
46
+ <Card sx={{ mb: 1 }} className='dash-widget'>
47
+ <Box
48
+ sx={{ p: 1 }}
49
+ style={{ display: 'flex', alignItems: 'center' }}
50
+ >
51
+ <span className='card-title'>Configuración</span>
52
+ </Box>
53
+ <Box sx={{ p: 1 }}>{render('Configuración')}</Box>
54
+ </Card>
55
+ </Grid>
56
+ </Grid>
57
+ </Grid>
58
+ </Grid>
59
+
60
+ );};
61
+
62
+ export default userLayout;
@@ -0,0 +1,111 @@
1
+ import { IDashAutoAdminResourceConfig } from 'dash-auto-admin';
2
+ import ResourceTemplate from '../../templates/ResourceTemplate';
3
+ import Settings from '@mui/icons-material/Settings';
4
+
5
+
6
+ import { PaginationComponent } from 'dash-components';
7
+
8
+ import { Card } from '@mui/material';
9
+ import { downloadCSV } from 'react-admin';
10
+ import {DASHAppConstants} from 'dash-constants';
11
+ import jsonExport from 'jsonexport/dist';
12
+ import {DASHAdminSystemConstants} from 'dash-constants';
13
+ import userLayout from './userLayout';
14
+ import userSchema from './userSchema';
15
+ import { NoResults } from '../../components/misc/NoResults';
16
+ import usersFilters from './usersFilters';
17
+
18
+ /**
19
+ * Shared tenant-user CRUD resource (list/create/edit/trash for `tenant/user`).
20
+ *
21
+ * Moved here from kt-ecommerce (resources/user/userResource.tsx) - nothing in
22
+ * this config is kitchntabs- or vanexa-specific (model, schema, layout and
23
+ * filters were all already generic; the only reason it lived in kt-ecommerce
24
+ * was history), so every app - kitchntabs-* and vanexa-* alike - should
25
+ * consume this single copy instead of each domain package carrying its own.
26
+ */
27
+ const userResource: IDashAutoAdminResourceConfig = {
28
+ filterWithSubmit: true,
29
+ roles: [
30
+ DASHAdminSystemConstants.system.DASH_SYSTEM_ROLE,
31
+ DASHAppConstants.system.TENANT_ROLE,
32
+ ],
33
+ component: ResourceTemplate,
34
+ trash: true,
35
+ model: 'tenant/user',
36
+
37
+ schema: userSchema,
38
+ icon: <Settings />,
39
+
40
+ group: "resource.groups.configuration",
41
+ label: "resource.ecommerce.users.label",
42
+
43
+ menu: [
44
+ {
45
+ title: 'Usuarios',
46
+ redirect: '/tenant/user',
47
+ },
48
+ {
49
+ title: "🗑",
50
+ redirect: "/tenant/user/trash",
51
+ }
52
+ ],
53
+ resourceMenuDisabled: false,
54
+ refreshAfter:true,
55
+ /*customListActions: (props) => {
56
+ const { children } = props;
57
+ return <Card sx={{ mb: 2 }} className='dash-card-content dash-module top-toolbar'>{children}</Card>;
58
+ },*/
59
+ isFormData: true,
60
+ /** @deprecated TODO: side effects? seems is not implemented anywhere */
61
+ listEditButton: { enabled: true },
62
+
63
+ postFormatter: (params, _method) => {
64
+ if (!params.avatar) {
65
+ // delete the param if value is falsy, undefined, null, etc..
66
+ delete params.avatar;
67
+ }
68
+ return params;
69
+ },
70
+ dataGridProps: { stickyHeader: true, empty: <NoResults />, bulkActionButtons: false },
71
+ listProps: { perPage: DASHAdminSystemConstants.system.DEFAULT_PER_PAGE || 50, empty: false },
72
+ dataGridWrapper: (props) => {
73
+ const { children } = props;
74
+ return <div className='sticky-header-wrapper'>{children}</div>;
75
+ },
76
+ redirectAfterUpdate: false,
77
+ createLayout: userLayout,
78
+ editLayout: userLayout,
79
+ formGroupMode: 'layout',
80
+ /*exporter: (clients) => {
81
+ const clientsForExport = clients.map((client) => {
82
+ return client;
83
+ });
84
+ jsonExport(
85
+ clientsForExport,
86
+ {
87
+ //headers: ['id', 'title', 'author_name', 'body'] // order fields in the export
88
+ },
89
+ (err, csv) => {
90
+ downloadCSV(csv, 'clientes');
91
+ },
92
+ );
93
+ },*/
94
+ create: true,
95
+ edit: true,
96
+ view: false,
97
+ listViewButton: { enabled: false },
98
+ toolbarCreateButton: { enabled: true },
99
+ toolbarEditButton: { enabled: false },
100
+ toolbarExportButton: { enabled: false },
101
+ toolbarListButton: { enabled: true },
102
+ listDeleteButton: { enabled: true, props: { confirm: true } },
103
+ Pagination: PaginationComponent,
104
+ drawer: false,
105
+
106
+ mutationMode: 'pessimistic',
107
+ referenceFilters: usersFilters,
108
+
109
+ };
110
+
111
+ export default userResource;
@@ -0,0 +1,213 @@
1
+ import { IDashAutoAdminAttribute } from 'dash-auto-admin';
2
+
3
+
4
+ import { SelectArrayInput } from 'react-admin';
5
+ import { RutValidator } from '../../utils/validators';
6
+ import AvatarUploadField from './components/AvatarUploadField';
7
+ import PasswordFields from './components/PasswordFields';
8
+ const userSchema: IDashAutoAdminAttribute[] = [
9
+ {
10
+ tab: 'Datos del usuario',
11
+ attribute: 'id',
12
+ label: 'Id',
13
+ type: String,
14
+ sortable: true,
15
+ inEdit: false,
16
+ inCreate: false,
17
+
18
+ },
19
+ {
20
+ tab: 'Datos del usuario',
21
+ attribute: 'public_id',
22
+ label: 'Rut',
23
+ type: String,
24
+ fieldOptions: { required: true/*, validate: [required()],*/, showDiv: true, fullWidth: true },
25
+ sortable: true,
26
+ inEdit: true,
27
+ inCreate: true,
28
+ inShow: true,
29
+ inList: false,
30
+ validate: (value) => {
31
+
32
+ if (!value) throw Error('El campo es requerido');
33
+
34
+ if (!RutValidator(value)) {
35
+ throw Error('El Rut es inválido');
36
+ }
37
+ }
38
+ },
39
+ {
40
+ tab: 'Datos del usuario',
41
+ attribute: 'name',
42
+ label: 'Nombre',
43
+ type: String,
44
+ sortable: true,
45
+ inEdit: true,
46
+ inCreate: true,
47
+ inShow: false,
48
+ inList: false,
49
+ fieldOptions: { required: true }
50
+
51
+ },
52
+ {
53
+ tab: 'Datos del usuario',
54
+ attribute: 'lastname',
55
+ label: 'Apellido',
56
+ type: String,
57
+ sortable: true,
58
+ inEdit: true,
59
+ inCreate: true,
60
+ inShow: true,
61
+ inList: false,
62
+ fieldOptions: { required: true }
63
+ },
64
+
65
+ {
66
+ tab: 'Datos del usuario',
67
+ attribute: 'full_name',
68
+ label: 'Nombre',
69
+ type: String,
70
+ sortable: true,
71
+ inEdit: false,
72
+ inShow: true,
73
+ inCreate: false,
74
+ fieldOptions: { required: true }
75
+ },
76
+ {
77
+ tab: 'Datos del usuario',
78
+ attribute: 'email',
79
+ label: 'Email',
80
+ type: String,
81
+ sortable: true,
82
+ inEdit: true,
83
+ inShow: true,
84
+ inCreate: true,
85
+ fieldOptions: { required: true }
86
+ },
87
+ {
88
+ tab: 'Datos del usuario',
89
+ attribute: 'phone',
90
+ label: 'Telefono',
91
+ type: String,
92
+ sortable: true,
93
+ inEdit: true,
94
+ inCreate: true,
95
+ inShow: true,
96
+ inList: false,
97
+ },
98
+ /*{
99
+ tab: 'Configuración',
100
+ attribute: 'active',
101
+ type: Boolean,
102
+ inList: true,
103
+ inCreate: false,
104
+ label: 'Activo',
105
+ showLabel: false,
106
+ processor: 'Boolean',
107
+ },*/
108
+
109
+ {
110
+ tab: 'Credenciales',
111
+ attribute: 'password',
112
+ label: 'Contraseña',
113
+ type: String,
114
+ sortable: true,
115
+ inEdit: false,
116
+ inCreate: false,
117
+ inShow: false,
118
+ inList: false,
119
+ },
120
+ {
121
+ tab: 'Credenciales',
122
+ attribute: 'password_confirmation',
123
+ label: 'Confirma Contraseña',
124
+ type: String,
125
+ sortable: true,
126
+ inEdit: false,
127
+ inCreate: false,
128
+ inShow: false,
129
+ inList: false,
130
+ },
131
+ /*{
132
+ tab: 'Credenciales',
133
+ attribute: 'role_id',
134
+ type: 'system/role/forSelect.name',
135
+ label: 'Rol de usuario',
136
+ componentProps: {
137
+ filter: { substitutable: true } // Shows only substituable roles for current user, backend logic.
138
+ },
139
+ sortable: true,
140
+ inEdit: true,
141
+ inCreate: true,
142
+ inShow: true,
143
+ inList: false,
144
+ multiple: false,
145
+ },*/
146
+ {
147
+ tab: "Credenciales",
148
+ label: 'Roles',
149
+ attribute: 'role_ids',
150
+ //listAttribute: 'name',
151
+ // system/role is core-owned and works for every domain (kitchntabs-*, vanexa-*),
152
+ // unlike tenant/role which only exists in kitchntabs-backend-domain
153
+ // (Domain\App\Http\Controllers\API\ECommerce\RoleController — an empty
154
+ // Domain\App\Models\ECommerce\Role subclass of the same core Role/roles table,
155
+ // with equivalent privilege-level-based visibility filtering).
156
+ type: 'system/role/forSelect.name',
157
+ //type: Object,
158
+ // TODO Agregar un filtro, solo para traer los roles de cliente.
159
+ pagination: false,
160
+ multiple: true,
161
+ //custom: true,
162
+ //componentProps:{ options: {fullwidth: true} },
163
+ component: SelectArrayInput,
164
+ //searchField: "subdomain"
165
+ },
166
+ {
167
+ // @TODO Solo mostrar cuando se está creando:
168
+ label: 'Genear Contraseña Aleatorea Automáticamente',
169
+ attribute: 'generate_password',
170
+ type: Boolean,
171
+ inList: false,
172
+ inEdit:false,
173
+ tab: 'Configuración',
174
+ },
175
+ {
176
+ attribute: 'active',
177
+ type: Boolean,
178
+ inList: true,
179
+ label: 'Activo',
180
+ tab: 'Configuración',
181
+ processor: 'Boolean',
182
+ },
183
+ {
184
+ tab: 'Avatar',
185
+ attribute: 'avatar',
186
+ listAttribute: 'image_url',
187
+ label: 'Foto Usuario',
188
+ type: String,
189
+ sortable: true,
190
+ inEdit: true,
191
+ inCreate: true,
192
+ inShow: true,
193
+ inList: false,
194
+ custom: true,
195
+ component: AvatarUploadField,
196
+ processor: 'File',
197
+ },
198
+ {
199
+ tab: 'Credenciales',
200
+ attribute: 'password',
201
+ label: 'Contraseña',
202
+ type: String,
203
+ sortable: true,
204
+ inList: false,
205
+ inEdit: true,
206
+ inCreate: true,
207
+ custom: true,
208
+ inShow: false,
209
+ component: PasswordFields,
210
+ },
211
+ ];
212
+
213
+ export default userSchema;
@@ -0,0 +1,21 @@
1
+ import IReferenceFilter from 'dash-auto-admin/src/interfaces/IReferenceFilter';
2
+ const usersReferenceFilters: IReferenceFilter[] = [
3
+ {
4
+ id: 'q',
5
+ label: 'Nombres/Email/Busqueda General',
6
+ source: 'q',
7
+ alwaysOn: true,
8
+ reference: null,
9
+ optionText: null,
10
+ },
11
+ {
12
+ id: 'email',
13
+ label: 'Email',
14
+ source: 'email',
15
+ alwaysOn: true,
16
+ reference: null,
17
+ optionText: null,
18
+ },
19
+ ];
20
+
21
+ export default usersReferenceFilters;
@@ -11,6 +11,8 @@ import Avatar from './components/avatar/Avatar';
11
11
  import SystemUpdateAlt from '@mui/icons-material/SystemUpdateAlt';
12
12
  import Person from '@mui/icons-material/Person';
13
13
  import CardMembershipIcon from '@mui/icons-material/CardMembership';
14
+ import PaidIcon from '@mui/icons-material/Paid';
15
+ import TranslateIcon from '@mui/icons-material/Translate';
14
16
  import { lazy } from 'react';
15
17
  import BusinessIcon from "@mui/icons-material/Business";
16
18
  import Chip from "@mui/material/Chip";
@@ -969,12 +971,19 @@ const systemResources: IAppResourceConfig[] = [
969
971
  },
970
972
 
971
973
 
974
+ // ============ Currency Management (core shared master data) ============
975
+ // Backed by dash-backend core's system/currency route (App\Http\Controllers\
976
+ // API\System\CurrencyController). Previously pointed at the domain's
977
+ // ecommerce/currency route — currencies moved to core as "shared master
978
+ // data" (see CLAUDE.md's core/domain split), so every app using this
979
+ // shared systemResources manifest (kitchntabs-*, vanexa-*) now gets a
980
+ // working Currencies page with no domain layer required.
972
981
  {
973
982
  roles: [DASHAppConstants.system.SYSTEM_ROLE],
974
983
  component: ResourceTemplate,
975
984
  trash: true,
976
- model: "ecommerce/currency",
977
- label: "resource.ecommerce.currencies.label",
985
+ model: "system/currency",
986
+ label: "resource.system.currencies.label",
978
987
  schema: [
979
988
  {
980
989
  label: 'Código',
@@ -983,7 +992,6 @@ const systemResources: IAppResourceConfig[] = [
983
992
  fieldOptions: {
984
993
  helperText: 'E.g: CLP | USD ...'
985
994
  }
986
-
987
995
  },
988
996
  {
989
997
  label: 'Formato',
@@ -1012,24 +1020,21 @@ const systemResources: IAppResourceConfig[] = [
1012
1020
  component: FormatCurrency
1013
1021
  },
1014
1022
  ],
1015
- //references: [{ reference: 'roles', target: 'role', schema: rolesSchema }]
1016
- //references: [{ reference: 'roles', target: 'id', schema: roleSchema }],
1017
- icon: <Person />,
1018
- // group: "resource.groups.system_resources",
1023
+ icon: <PaidIcon />,
1019
1024
  group: "System",
1020
1025
  menu: [
1021
1026
  {
1022
- title: "resource.ecommerce.currencies.menu_list",
1023
- redirect: "/ecommerce/currency",
1027
+ title: "resource.system.currencies.menu_list",
1028
+ redirect: "/system/currency",
1024
1029
  },
1025
1030
  {
1026
1031
  title: "🗑",
1027
- redirect: "/ecommerce/currency/trash",
1032
+ redirect: "/system/currency/trash",
1028
1033
  },
1029
1034
  ],
1030
1035
 
1031
1036
  mainAction: {
1032
- title: "resource.ecommerce.currencies.main_action",
1037
+ title: "resource.system.currencies.main_action",
1033
1038
  mode: "create",
1034
1039
  fn: "virtualhash",
1035
1040
  redirect: "inline/create",
@@ -1043,17 +1048,23 @@ const systemResources: IAppResourceConfig[] = [
1043
1048
 
1044
1049
  mutationMode: "pessimistic",
1045
1050
  saveButtonAlwaysEnabled: true,
1046
- listProps: { storeKey: false, filterDefaultValues: { show_disabled: true } }, // deshabilita persistencia deel estado, cache de los valores seleccionados sort, page, etc.
1051
+ listProps: { storeKey: false, filterDefaultValues: { show_disabled: true } },
1047
1052
  resetSelectedIdsOnLoad: true,
1048
1053
  },
1049
1054
 
1050
- // ============ Language Management ============
1055
+ // ============ Language Management (core shared master data) ============
1056
+ // Backed by dash-backend core's system/language route (App\Http\Controllers\
1057
+ // API\System\LanguageController). Previously pointed at the domain's
1058
+ // common/language route — languages moved to core as "shared master data"
1059
+ // (see CLAUDE.md's core/domain split), so every app using this shared
1060
+ // systemResources manifest (kitchntabs-*, vanexa-*) now gets a working
1061
+ // Languages page with no domain layer required.
1051
1062
  {
1052
1063
  roles: [DASHAppConstants.system.SYSTEM_ROLE],
1053
1064
  component: ResourceTemplate,
1054
1065
  trash: true,
1055
- model: "common/language",
1056
- label: "resource.common.languages.label",
1066
+ model: "system/language",
1067
+ label: "resource.system.languages.label",
1057
1068
  schema: [
1058
1069
  {
1059
1070
  label: 'Code',
@@ -1097,21 +1108,21 @@ const systemResources: IAppResourceConfig[] = [
1097
1108
  }
1098
1109
  },
1099
1110
  ],
1100
- icon: <Person />,
1111
+ icon: <TranslateIcon />,
1101
1112
  group: "System",
1102
1113
  menu: [
1103
1114
  {
1104
- title: "resource.common.languages.menu_list",
1105
- redirect: "/common/language",
1115
+ title: "resource.system.languages.menu_list",
1116
+ redirect: "/system/language",
1106
1117
  },
1107
1118
  {
1108
1119
  title: "🗑",
1109
- redirect: "/common/language/trash",
1120
+ redirect: "/system/language/trash",
1110
1121
  },
1111
1122
  ],
1112
1123
 
1113
1124
  mainAction: {
1114
- title: "resource.common.languages.main_action",
1125
+ title: "resource.system.languages.main_action",
1115
1126
  mode: "create",
1116
1127
  fn: "virtualhash",
1117
1128
  redirect: "inline/create",