@dashadmin/dash-admin 1.3.73 → 1.3.74-srcfree.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/tenant/TenancyPlan.js +307 -0
- package/dist/systemResources.js +18 -2
- package/package.json +25 -22
- package/src/AppAsyncWrapper.tsx +0 -42
- package/src/AppWrapper.tsx +0 -45
- package/src/DASHAdmin.tsx +0 -502
- package/src/DASHAdmin.tsx.old +0 -456
- package/src/RoutingWrapper.tsx +0 -143
- package/src/classes/DASHStorageClass.tsx +0 -8
- package/src/components/Input/RichTextField.tsx +0 -27
- package/src/components/Redirect.tsx +0 -46
- package/src/components/avatar/Avatar.tsx +0 -71
- package/src/components/avatar/SingleImageUploader.tsx +0 -107
- package/src/components/currency/Format.tsx +0 -79
- package/src/components/custom/Redirect.tsx +0 -23
- package/src/components/error/Error.tsx +0 -168
- package/src/components/geocoding/GeocodingField.tsx +0 -167
- package/src/components/i18n/BridgedLocalesMenuButton.tsx +0 -160
- package/src/components/i18n/LangSwitcher.tsx +0 -204
- package/src/components/loader/GlobalLoader.tsx +0 -49
- package/src/components/logs/LogFile.tsx +0 -88
- package/src/components/logs/LogFileById.tsx +0 -68
- package/src/components/logs/LogViewer.tsx +0 -43
- package/src/components/menu/AppMenu.tsx +0 -22
- package/src/components/menu/CustomMenuItemLink.tsx +0 -61
- package/src/components/menu/DarkToggleMode.tsx +0 -65
- package/src/components/menu/LanguageToggleMode.tsx +0 -120
- package/src/components/misc/CustomImageInput.tsx +0 -62
- package/src/components/misc/DASHGlobalErrorHandler.tsx +0 -194
- package/src/components/misc/DarkModeSwitcher.tsx +0 -112
- package/src/components/misc/HorizontalScroller.tsx +0 -225
- package/src/components/misc/LanguageSwitcher.tsx +0 -199
- package/src/components/misc/MUIHtmlToolTip.tsx +0 -15
- package/src/components/misc/MuiSimpleJsonTable.tsx +0 -279
- package/src/components/misc/MultiLevelTable.tsx +0 -229
- package/src/components/misc/NoResults.tsx +0 -28
- package/src/components/misc/PDFViewer.tsx +0 -85
- package/src/components/navigation/Breadcrumbs.tsx +0 -220
- package/src/components/navigation/BreadcrumbsManager.tsx +0 -310
- package/src/components/navigation/index.tsx +0 -5
- package/src/components/panel/Error.tsx +0 -168
- package/src/components/permission/AvailablePermissionsContext.tsx +0 -173
- package/src/components/permission/PermissionsSelector.tsx +0 -834
- package/src/components/permission/PermissionsSelectorList.tsx +0 -473
- package/src/components/permission/tsx +0 -0
- package/src/components/racustombuttons/CustomRAButton.tsx +0 -87
- package/src/components/racustombuttons/QuickButton.tsx +0 -117
- package/src/components/racustombuttons/QuickEditButton.tsx +0 -115
- package/src/components/racustombuttons/QuickIconButton.tsx +0 -122
- package/src/components/scrollbar/Scrollbar.tsx +0 -31
- package/src/components/selects/MultiSelect.tsx +0 -53
- package/src/components/selects/RASearchableSelect.tsx +0 -282
- package/src/components/selects/RASearchableSelectChips.tsx +0 -308
- package/src/components/selects/SearchableSelect.tsx +0 -139
- package/src/components/serviceAccount/ApiKeyRevealDialog.tsx +0 -129
- package/src/components/serviceAccount/ServiceAccountStatusSwitch.tsx +0 -99
- package/src/components/subscription/BillingCycleSelectInput.tsx +0 -68
- package/src/components/subscription/PlanAddonsSettings.tsx +0 -563
- package/src/components/subscription/PlanAuditLog.tsx +0 -453
- package/src/components/subscription/PlanFeaturesSettings.tsx +0 -243
- package/src/components/subscription/PlanLimitsSettings.tsx +0 -230
- package/src/components/subscription/PlanMetadataSettings.tsx +0 -306
- package/src/components/subscription/PlanPricesSettings.tsx +0 -307
- package/src/components/subscription/index.ts +0 -7
- package/src/components/svgelements/SvgLoading.tsx +0 -229
- package/src/components/svgelements/SvgLogo.tsx +0 -53
- package/src/components/svgelements/SvgLogoMin.tsx +0 -64
- package/src/components/svgelements/SvgShipping.tsx +0 -673
- package/src/components/tenancy/GlobalTenantWrapper.tsx +0 -84
- package/src/components/tenancy/TenantSwitcher.tsx +0 -514
- package/src/components/tenant/AvailablePermissionsContext.tsx +0 -0
- package/src/components/tenant/SettingsSections.tsx +0 -151
- package/src/components/tenant/TenancySettings.tsx +0 -122
- package/src/components/tenant/TenantAttributes.tsx +0 -153
- package/src/components/tenant/TenantAttributesContext.tsx +0 -163
- package/src/components/tenant/TenantSelector.tsx +0 -142
- package/src/components/tenant/TenantSettings.tsx +0 -184
- package/src/components/tenant/TenantSettingsContext.tsx +0 -165
- package/src/components/tenant/TenantTheme.tsx +0 -172
- package/src/components/user/AvatarComponent.tsx +0 -317
- package/src/components/user/TenantAvatarComponent.tsx +0 -99
- package/src/components/user/UserPreferences.tsx +0 -677
- package/src/config/ACTIONS.tsx +0 -26
- package/src/config/ConstantsService.tsx +0 -44
- package/src/config/DASHAdminSystemConstants.tsx +0 -183
- package/src/config/PARSERS.tsx +0 -9
- package/src/contexts/DashQueryClientContext.tsx +0 -113
- package/src/contexts/DashResourceContext.tsx +0 -34
- package/src/contexts/I18nBridgeContext.tsx +0 -156
- package/src/contexts/I18nBridgeSetter.tsx +0 -39
- package/src/contexts/I18nReduxSync.tsx +0 -27
- package/src/contexts/SubscriptionPlanFormatsProvider.tsx +0 -217
- package/src/contexts/SystemRequestsCache.tsx +0 -215
- package/src/contexts/auth/AuthContext.tsx +0 -567
- package/src/contexts/auth/AuthContextLocalStorage.tsx +0 -140
- package/src/contexts/auth/DASHAuthenticationService.tsx +0 -915
- package/src/contexts/auth/WindowContext.tsx +0 -15
- package/src/contexts/auth/index.tsx +0 -3
- package/src/contexts/com/FCMContext.tsx +0 -415
- package/src/contexts/com/LaravelEchoContext.tsx +0 -41
- package/src/contexts/com/LaravelEchoMgr.tsx +0 -155
- package/src/contexts/com/components/DefaultNotificationComponent.tsx +0 -20
- package/src/contexts/com/components/EchoNotificationsCenter.tsx +0 -65
- package/src/contexts/com/components/NotificationAttributesTable.tsx +0 -54
- package/src/contexts/com/components/NotificationRenderer.tsx +0 -42
- package/src/contexts/com/components/NotificationsWidget.tsx +0 -182
- package/src/contexts/com/components/notificationFormats.tsx +0 -50
- package/src/contexts/com/useLaravelEcho.tsx +0 -432
- package/src/contexts/dictionary/DictionaryContext.tsx +0 -94
- package/src/declarations.d.ts +0 -17
- package/src/default-theme/DASHAppProviders.tsx +0 -117
- package/src/default-theme/DashThemeContext.tsx +0 -209
- package/src/default-theme/DashThemeContext.tsx.fast +0 -143
- package/src/default-theme/DashThemeContext.tsx.old +0 -306
- package/src/default-theme/DashThemeHelperProvider.tsx +0 -98
- package/src/default-theme/DomainAppLayout.tsx +0 -166
- package/src/default-theme/DomainHeader.tsx +0 -162
- package/src/default-theme/DomainTheme.tsx +0 -59
- package/src/default-theme/FullLayoutMarkup.tsx +0 -231
- package/src/default-theme/StaticLayout.tsx +0 -47
- package/src/default-theme/index.tsx +0 -11
- package/src/default-theme/menu/AppDashboardGrid.tsx +0 -279
- package/src/default-theme/menu/AppMaterialMenu.tsx +0 -546
- package/src/default-theme/menu/AppMenuComponents/SubmenuPortal.tsx +0 -61
- package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.tsx +0 -264
- package/src/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.tsx +0 -31
- package/src/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.tsx +0 -293
- package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +0 -92
- package/src/default-theme/menu/AppMenuComponents/getItem.tsx +0 -17
- package/src/default-theme/menu/AppMenuComponents/interfaces.tsx +0 -41
- package/src/default-theme/menu/AppMenuComponents/submenuConstants.ts +0 -90
- package/src/default-theme/menu/AppSidebarMaterial.tsx +0 -339
- package/src/default-theme/menu/SidebarActions.tsx +0 -84
- package/src/default-theme/updateDomCssVariables.tsx +0 -176
- package/src/helpers/checkRole.tsx +0 -66
- package/src/helpers/parseAxiosError.tsx +0 -41
- package/src/hooks/audio/useAudio.tsx +0 -39
- package/src/hooks/axios.tsx +0 -165
- package/src/hooks/data/useDashboardStats.tsx +0 -65
- package/src/hooks/data/usePackageByClientsStats.tsx +0 -44
- package/src/hooks/data/usePackageByCommunesStats.tsx +0 -44
- package/src/hooks/data/usePackageStats.tsx +0 -69
- package/src/hooks/data/usePackageWithdrawDetails.tsx +0 -61
- package/src/hooks/data/useStats.tsx +0 -86
- package/src/hooks/isCurrentPath.tsx +0 -22
- package/src/hooks/notifications/WSMessagesManager.tsx +0 -152
- package/src/hooks/notifications/WSPusherManager.tsx +0 -92
- package/src/hooks/useBreadcrumbs.tsx +0 -329
- package/src/hooks/useClickOutside.tsx +0 -57
- package/src/hooks/useFormPersistance.tsx +0 -150
- package/src/hooks/useGlobalErrorMediator.tsx +0 -43
- package/src/hooks/useGlobalLoaderMgr.tsx +0 -21
- package/src/hooks/useHash.tsx +0 -27
- package/src/hooks/useLocalStorage.tsx +0 -196
- package/src/hooks/usePolyglotTranslation.tsx +0 -62
- package/src/hooks/usePrevious.tsx +0 -9
- package/src/hooks/usePrintSelected.tsx +0 -37
- package/src/hooks/useVirtualHash.tsx +0 -33
- package/src/hooks/window/useWindowSize.tsx +0 -36
- package/src/index.tsx +0 -134
- package/src/interfaces/IAppResourceConfig.tsx +0 -20
- package/src/interfaces/Log.tsx +0 -16
- package/src/interfaces/Tenant.tsx +0 -25
- package/src/interfaces/communication/IActions.tsx +0 -5
- package/src/interfaces/communication/INotification.tsx +0 -21
- package/src/interfaces/communication/IPayload.tsx +0 -3
- package/src/interfaces/communication/IRequestAction.tsx +0 -10
- package/src/interfaces/communication/IRequestPayload.tsx +0 -7
- package/src/interfaces/communication/IResponseAction.tsx +0 -7
- package/src/interfaces/misc/IAny.tsx +0 -3
- package/src/interfaces/misc/IFlashMessage.tsx +0 -10
- package/src/interfaces/navigation/IAppMenu.ts +0 -14
- package/src/interfaces/navigation/ICollapsableSidebarMenu.ts +0 -12
- package/src/interfaces/navigation/IMenuItem.ts +0 -16
- package/src/interfaces/notifications/IModel.tsx +0 -6
- package/src/interfaces/notifications/IModelField.tsx +0 -8
- package/src/interfaces/notifications/IUserNotification.tsx +0 -12
- package/src/interfaces/notifications/IUserNotificationData.tsx +0 -13
- package/src/interfaces/notifications/IUserNotificationPayload.tsx +0 -8
- package/src/interfaces/user/IGetAuth.tsx +0 -92
- package/src/interfaces/user/ITenantSettings.tsx +0 -3
- package/src/interfaces/user/IUser.tsx +0 -60
- package/src/interfaces/user/IUserSettings.tsx +0 -43
- package/src/interfaces.tsx +0 -6
- package/src/layout/AppLayout.tsx +0 -112
- package/src/layout/ApplicationLayout.tsx +0 -197
- package/src/layout/MotionWrapper.original.tsx +0 -236
- package/src/layout/MotionWrapper.tsx +0 -236
- package/src/layout/ResourceMenu.tsx +0 -164
- package/src/layout/ResoureLayout.tsx +0 -105
- package/src/layout/TransitionWrapper.tsx +0 -125
- package/src/pages/ChangePassword.tsx +0 -179
- package/src/pages/DASHLanding.tsx +0 -22
- package/src/pages/DASHLightWeightLogin.tsx +0 -611
- package/src/pages/DASHSimpleLogin.tsx +0 -260
- package/src/pages/Login.tsx +0 -111
- package/src/pages/Profile.tsx +0 -357
- package/src/pages/RecoverPassword.tsx +0 -175
- package/src/pages/SingleImageUploader.tsx +0 -55
- package/src/pages/VerifyAccount.tsx +0 -128
- package/src/providers/authProvider.tsx +0 -217
- package/src/providers/dataProvider.tsx +0 -672
- package/src/providers/i18n/en.ts +0 -646
- package/src/providers/i18n/es.ts +0 -652
- package/src/providers/i18n/languages.tsx +0 -8
- package/src/providers/i18n/mergeTranslations.ts +0 -53
- package/src/providers/i18nProvider.tsx +0 -23
- package/src/react-admin-dash/RADashComponent.tsx +0 -240
- package/src/react-admin-dash/Resource.tsx +0 -77
- package/src/resources/Brand/BrandResource.tsx +0 -130
- package/src/resources/DASHResourceLoader.ts +0 -180
- package/src/resources/Log/LogResource.tsx +0 -73
- package/src/resources/Tenant/ImpersonateTenantResource.tsx +0 -113
- package/src/resources/Trash/TrashTemplate.tsx +0 -180
- package/src/resources/User/components/AvatarUploadField.tsx +0 -57
- package/src/resources/User/components/PasswordFields.tsx +0 -73
- package/src/resources/User/getProfileMenu.ts +0 -57
- package/src/resources/User/profileResource.tsx +0 -51
- package/src/resources/User/userLayout.tsx +0 -62
- package/src/resources/User/userResource.tsx +0 -111
- package/src/resources/User/userSchema.tsx +0 -213
- package/src/resources/User/usersFilters.tsx +0 -21
- package/src/resources.tsx +0 -280
- package/src/schemas/log.tsx +0 -45
- package/src/schemas/notification.tsx +0 -42
- package/src/schemas/permissions.tsx +0 -44
- package/src/schemas/roles.tsx +0 -48
- package/src/schemas/rolesDataGrid.tsx +0 -48
- package/src/schemas/subscription/components/SubscriptionActions.tsx +0 -153
- package/src/schemas/subscription/components/SubscriptionPaymentHistory.tsx +0 -127
- package/src/schemas/subscription/components/SubscriptionPlanFeatures.tsx +0 -162
- package/src/schemas/subscription/components/SubscriptionPlanPreview.tsx +0 -141
- package/src/schemas/subscription/components/SubscriptionPlanStats.tsx +0 -318
- package/src/schemas/subscription/components/SubscriptionStatusIndicator.tsx +0 -72
- package/src/schemas/subscription/subscriptionPlanSchema.tsx +0 -185
- package/src/schemas/subscription/subscriptionSchema.tsx +0 -152
- package/src/schemas/subscriptionPlan.ts +0 -422
- package/src/schemas/tenant.tsx +0 -129
- package/src/schemas/tenantUser.tsx +0 -96
- package/src/schemas/tenant_superadmin.tsx +0 -119
- package/src/schemas/user.tsx +0 -26
- package/src/systemResources.old.tsx +0 -928
- package/src/systemResources.tsx +0 -1369
- package/src/templates/ResourceTemplate.tsx +0 -240
- package/src/templates/ResourceTemplate.tsx.memoized_experiment +0 -350
- package/src/templates/ResourceTemplate.tsx.original +0 -396
- package/src/templates/ResourceTemplateCreate.tsx +0 -182
- package/src/templates/ResourceTemplateEdit.tsx +0 -176
- package/src/templates/ResourceTemplateFull.tsx +0 -581
- package/src/templates/ResourceTemplateList.tsx +0 -340
- package/src/templates/ResourceTemplateOld.tsx.bkup +0 -567
- package/src/templates/ResourceTemplateShow.tsx +0 -88
- package/src/templates/TrashTemplate.tsx +0 -179
- package/src/tenantResources.tsx +0 -223
- package/src/test_portal_bubbles.tsx +0 -40
- package/src/theme/AppHeader.tsx +0 -52
- package/src/theme/AppLayoutSetting.tsx +0 -33
- package/src/theme/AppLogo.tsx +0 -13
- package/src/theme/AppSidebar.tsx +0 -12
- package/src/theme/AppSidebarContent.tsx +0 -105
- package/src/theme/AppSidebarLogo.tsx +0 -48
- package/src/theme/components/PageTitle.tsx +0 -37
- package/src/utils/cache/CacheInvalidatorContext.tsx +0 -125
- package/src/utils/cache/CacheInvalidatorListenerComponent.tsx +0 -10
- package/src/utils/cache/useCacheInvalidatorListener.tsx +0 -27
- package/src/utils/convertFileToBase64.tsx +0 -9
- package/src/utils/convertToFile.tsx +0 -14
- package/src/utils/cookies.tsx +0 -33
- package/src/utils/dashDefaultQueryClient.tsx +0 -34
- package/src/utils/dataUrlToBlob.tsx +0 -30
- package/src/utils/deepReplace.tsx +0 -19
- package/src/utils/getProfileMenu.tsx +0 -41
- package/src/utils/getTenantSettings.tsx +0 -9
- package/src/utils/getType.tsx +0 -8
- package/src/utils/getUserSettings.tsx +0 -8
- package/src/utils/hasCode.tsx +0 -14
- package/src/utils/index.ts +0 -19
- package/src/utils/injectTenantStyles.ts +0 -28
- package/src/utils/isComponent.tsx +0 -45
- package/src/utils/navEvents.tsx +0 -91
- package/src/utils/prototypes.tsx +0 -5
- package/src/utils/regexp.tsx +0 -4
- package/src/utils/resolveObjectPath.tsx +0 -4
- package/src/utils/setNativeValue.tsx +0 -24
- package/src/utils/slugify.tsx +0 -11
- package/src/utils/validators/emailValidator.tsx +0 -6
- package/src/utils/validators/requiredValidator.tsx +0 -5
- package/src/utils/validators/rutValidator.tsx +0 -31
- package/src/utils/validators.tsx +0 -96
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ISearchableSelect for AutoAdmin for ReactAdmin
|
|
3
|
-
* @author Franisco Aranda <francisco.aranda@dash.cl> <faranda@gmail.com>
|
|
4
|
-
* @author Omar Muñoz <omar.munoz@dash.cl>
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Autocomplete,
|
|
9
|
-
Box,
|
|
10
|
-
Chip,
|
|
11
|
-
CircularProgress,
|
|
12
|
-
InputLabel,
|
|
13
|
-
TextField,
|
|
14
|
-
} from '@mui/material';
|
|
15
|
-
import React, { useEffect, useState } from 'react';
|
|
16
|
-
import { useController } from 'react-hook-form';
|
|
17
|
-
import { useGetList } from 'react-admin';
|
|
18
|
-
import { IDashAutoAdminCustomFieldComponent } from 'dash-auto-admin';
|
|
19
|
-
import { useRecordContext } from 'react-admin';
|
|
20
|
-
import { Loading } from 'react-admin';
|
|
21
|
-
import { isArray } from 'lodash';
|
|
22
|
-
import { LoadingIndicator } from 'react-admin';
|
|
23
|
-
|
|
24
|
-
interface ISearchableSelectChipsControl {
|
|
25
|
-
name?: string;
|
|
26
|
-
resource?: string;
|
|
27
|
-
selectLabel?: string;
|
|
28
|
-
title?: string;
|
|
29
|
-
renderText: (option: any, caller: string) => any;
|
|
30
|
-
transformData?: (val: any) => any; // onChange transformData from the search result item object to the field value (it usually needs to store the id)
|
|
31
|
-
defaultValues?: any;
|
|
32
|
-
isMultiple?: boolean;
|
|
33
|
-
//pagination?: boolean,
|
|
34
|
-
minSearch?: number;
|
|
35
|
-
searchResults?: number;
|
|
36
|
-
timerSearch?: number;
|
|
37
|
-
isEmpty?: boolean;
|
|
38
|
-
filter?: { [x: string]: any };
|
|
39
|
-
queryFilter?: string;
|
|
40
|
-
isOptionEqualToValue: (option: any, value: any) => boolean;
|
|
41
|
-
//_transformOptionEqualToValue?: (option: any, value: any) => boolean
|
|
42
|
-
viewAttribute: string;
|
|
43
|
-
valueKeyId?: string;
|
|
44
|
-
useBaseAttributeName?: boolean;
|
|
45
|
-
useListAttributeForController?: boolean;
|
|
46
|
-
transformOption?: (
|
|
47
|
-
option: any,
|
|
48
|
-
parsedOptions: any[],
|
|
49
|
-
caller?: string,
|
|
50
|
-
) => boolean;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const getDescendantProp = (obj, desc) => {
|
|
54
|
-
var arr = desc.split('.');
|
|
55
|
-
while (arr.length && (obj = obj[arr.shift()]));
|
|
56
|
-
return obj;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export const SearchableSelectChipsControl: React.FC<
|
|
60
|
-
ISearchableSelectChipsControl & IDashAutoAdminCustomFieldComponent
|
|
61
|
-
> = ({
|
|
62
|
-
method,
|
|
63
|
-
attribute,
|
|
64
|
-
isMultiple = false,
|
|
65
|
-
//pagination = true,
|
|
66
|
-
searchResults = 50,
|
|
67
|
-
minSearch = 3,
|
|
68
|
-
timerSearch = 500,
|
|
69
|
-
resource,
|
|
70
|
-
selectLabel,
|
|
71
|
-
renderText,
|
|
72
|
-
transformData = (val: any) => val,
|
|
73
|
-
queryFilter = 'q',
|
|
74
|
-
defaultValues = undefined,
|
|
75
|
-
isEmpty = false,
|
|
76
|
-
filter,
|
|
77
|
-
isOptionEqualToValue = undefined,
|
|
78
|
-
viewAttribute = null,
|
|
79
|
-
valueKeyId = 'id',
|
|
80
|
-
useBaseAttributeName = false,
|
|
81
|
-
useListAttributeForController = false,
|
|
82
|
-
transformOption,
|
|
83
|
-
}) => {
|
|
84
|
-
// React Admin record
|
|
85
|
-
//console.log("useListAttributeForController", useListAttributeForController);
|
|
86
|
-
let attributeName = useListAttributeForController
|
|
87
|
-
? attribute.listAttribute
|
|
88
|
-
: attribute.attribute;
|
|
89
|
-
attributeName = useBaseAttributeName
|
|
90
|
-
? attributeName.split('.')[0]
|
|
91
|
-
: attributeName;
|
|
92
|
-
//console.log("attributeName", attributeName);
|
|
93
|
-
const record = useRecordContext();
|
|
94
|
-
const recordAttributeValue = useBaseAttributeName
|
|
95
|
-
? attributeName.split('.')[0]
|
|
96
|
-
: attributeName;
|
|
97
|
-
//console.log("RECORD VALUE", recordAttributeValue, record[recordAttributeValue]);
|
|
98
|
-
// sets the initial state of the select dropdown
|
|
99
|
-
const [open, setOpen] = useState(false);
|
|
100
|
-
// parsedOptions: stores the postprocessed list of elements returned from the search query
|
|
101
|
-
const [parsedOptions, setParsedOptions] = useState(null);
|
|
102
|
-
// q; the search query
|
|
103
|
-
const [q, setQ] = useState('');
|
|
104
|
-
// field, checks if the current record contains associated values to the attribute in which this control is associated
|
|
105
|
-
//console.log("USE CONTROLLER name", attributeName, attribute.attribute, record[recordAttributeValue]);
|
|
106
|
-
const _transformOption = (option: any, caller: string) => {
|
|
107
|
-
return typeof transformOption === 'function'
|
|
108
|
-
? transformOption(option, parsedOptions, caller)
|
|
109
|
-
: option;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const _processFieldValue = (value: any) => {
|
|
113
|
-
return value
|
|
114
|
-
? isMultiple && Array.isArray(value)
|
|
115
|
-
? value.map((valItem) =>
|
|
116
|
-
_transformOption(valItem, '_processFieldValue'),
|
|
117
|
-
)
|
|
118
|
-
: _transformOption(value, '_processFieldValue')
|
|
119
|
-
: isMultiple
|
|
120
|
-
? []
|
|
121
|
-
: null;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const _defaultValues = defaultValues
|
|
125
|
-
? _processFieldValue(defaultValues)
|
|
126
|
-
: record && getDescendantProp(record, recordAttributeValue)
|
|
127
|
-
? _processFieldValue(getDescendantProp(record, recordAttributeValue))
|
|
128
|
-
: isMultiple
|
|
129
|
-
? []
|
|
130
|
-
: null;
|
|
131
|
-
|
|
132
|
-
const field = useController({ name: attributeName /*, defaultValue*/ });
|
|
133
|
-
// Includes, sends an array of the current selected items of the select, the backend sends those items in the first position of the list.
|
|
134
|
-
let _inc =
|
|
135
|
-
record && getDescendantProp(record, recordAttributeValue)
|
|
136
|
-
? getDescendantProp(record, recordAttributeValue)
|
|
137
|
-
: [];
|
|
138
|
-
_inc = isArray(_inc) ? _inc : [_inc[valueKeyId]];
|
|
139
|
-
|
|
140
|
-
const includes = _inc
|
|
141
|
-
.filter((element) => element)
|
|
142
|
-
.map((element) =>
|
|
143
|
-
element.hasOwnProperty(valueKeyId) ? element[valueKeyId] : element,
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
// React Admin useGetList, to perform the search
|
|
147
|
-
|
|
148
|
-
const {
|
|
149
|
-
data: resourceSearchResults,
|
|
150
|
-
total: totalSearchResults,
|
|
151
|
-
isLoading: isResourceSearchLoading,
|
|
152
|
-
error: isResourceSearchErrored,
|
|
153
|
-
} = useGetList(resource, {
|
|
154
|
-
meta: { removeSortFilters: true },
|
|
155
|
-
filter: { [queryFilter]: q, ...filter, includes: includes },
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
useEffect(() => {
|
|
159
|
-
if (resourceSearchResults /*&& !isResourceSearchLoading*/) {
|
|
160
|
-
const resultsArray = Array.isArray(resourceSearchResults)
|
|
161
|
-
? resourceSearchResults
|
|
162
|
-
: Object.values(resourceSearchResults);
|
|
163
|
-
|
|
164
|
-
const _parsedOptions = resultsArray.map((ele) => {
|
|
165
|
-
return { ...ele, key: "option" + ele.id };
|
|
166
|
-
});
|
|
167
|
-
setParsedOptions(_parsedOptions);
|
|
168
|
-
//updateFieldValue(_parsedOptions);
|
|
169
|
-
}
|
|
170
|
-
// on component unload, set parsedOptions to []
|
|
171
|
-
}, [resourceSearchResults /*, isResourceSearchLoading*/]);
|
|
172
|
-
|
|
173
|
-
// search timeout
|
|
174
|
-
const [timeOutSearch, setTimeOutSearch] = useState(undefined);
|
|
175
|
-
// search debounde
|
|
176
|
-
const debounce = (fn: Function, delay = 500) => {
|
|
177
|
-
clearTimeout(timeOutSearch);
|
|
178
|
-
setTimeOutSearch(
|
|
179
|
-
setTimeout(() => {
|
|
180
|
-
fn();
|
|
181
|
-
}, delay),
|
|
182
|
-
);
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const updateFieldValue = (value) => {
|
|
186
|
-
const val = _processFieldValue(value);
|
|
187
|
-
//console.log("UPDATE FIELD VALUES", val)
|
|
188
|
-
field.field.onChange(val);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
/* useEffect(() => {
|
|
192
|
-
if (field && field.field && parsedOptions) {
|
|
193
|
-
updateFieldValue(record[recordAttributeValue]);
|
|
194
|
-
}
|
|
195
|
-
}, [parsedOptions])*/
|
|
196
|
-
|
|
197
|
-
return (
|
|
198
|
-
<>
|
|
199
|
-
{parsedOptions ? (
|
|
200
|
-
<Autocomplete
|
|
201
|
-
key={'autocomplete-' + attribute.attribute}
|
|
202
|
-
multiple={isMultiple}
|
|
203
|
-
loading={isResourceSearchLoading /*&& open*/}
|
|
204
|
-
fullWidth
|
|
205
|
-
freeSolo={true}
|
|
206
|
-
options={parsedOptions}
|
|
207
|
-
open={open}
|
|
208
|
-
onOpen={() => setOpen(true)}
|
|
209
|
-
onClose={() => setOpen(false)}
|
|
210
|
-
defaultValue={_defaultValues}
|
|
211
|
-
isOptionEqualToValue={isOptionEqualToValue}
|
|
212
|
-
autoHighlight
|
|
213
|
-
getOptionLabel={(option: any) =>
|
|
214
|
-
renderText(_transformOption(option, 'optionlabel'), 'optionlabel')
|
|
215
|
-
}
|
|
216
|
-
renderOption={(props, option: any) => {
|
|
217
|
-
const { key, ...newProps } = props as any;
|
|
218
|
-
return (
|
|
219
|
-
<Box
|
|
220
|
-
key={option.key}
|
|
221
|
-
component='li'
|
|
222
|
-
sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
|
|
223
|
-
{...newProps}
|
|
224
|
-
>
|
|
225
|
-
{renderText(_transformOption(option, 'option'), 'option')}
|
|
226
|
-
</Box>
|
|
227
|
-
);
|
|
228
|
-
}}
|
|
229
|
-
onChange={(event: any, rawValue) => {
|
|
230
|
-
setOpen(false);
|
|
231
|
-
updateFieldValue(rawValue);
|
|
232
|
-
}}
|
|
233
|
-
renderInput={(params) => {
|
|
234
|
-
return (
|
|
235
|
-
<TextField
|
|
236
|
-
key={params.id}
|
|
237
|
-
{...params}
|
|
238
|
-
label={selectLabel}
|
|
239
|
-
variant='outlined'
|
|
240
|
-
onChange={(ev) => {
|
|
241
|
-
let searchValue = ev.target.value;
|
|
242
|
-
if (
|
|
243
|
-
searchValue &&
|
|
244
|
-
searchValue !== '' &&
|
|
245
|
-
searchValue.length >= minSearch
|
|
246
|
-
)
|
|
247
|
-
debounce(() => setQ(searchValue), timerSearch);
|
|
248
|
-
}}
|
|
249
|
-
slotProps={{
|
|
250
|
-
...params.slotProps,
|
|
251
|
-
|
|
252
|
-
input: {
|
|
253
|
-
...params.slotProps.input,
|
|
254
|
-
autoComplete: 'new-password',
|
|
255
|
-
endAdornment: (
|
|
256
|
-
<>
|
|
257
|
-
{isResourceSearchLoading ? (
|
|
258
|
-
<CircularProgress color='inherit' size={20} />
|
|
259
|
-
) : null}
|
|
260
|
-
{params.slotProps.input.endAdornment}
|
|
261
|
-
</>
|
|
262
|
-
),
|
|
263
|
-
}
|
|
264
|
-
}}
|
|
265
|
-
/>
|
|
266
|
-
);
|
|
267
|
-
}}
|
|
268
|
-
/>
|
|
269
|
-
) : (
|
|
270
|
-
<LoadingIndicator />
|
|
271
|
-
)}
|
|
272
|
-
|
|
273
|
-
{!isMultiple && parsedOptions && _defaultValues && (
|
|
274
|
-
<>
|
|
275
|
-
<Chip
|
|
276
|
-
label={renderText(_transformOption(_defaultValues, 'chip'), 'chip')}
|
|
277
|
-
/>
|
|
278
|
-
</>
|
|
279
|
-
)}
|
|
280
|
-
</>
|
|
281
|
-
);
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const RASearchableSelectChips: React.FC<
|
|
285
|
-
IDashAutoAdminCustomFieldComponent & ISearchableSelectChipsControl
|
|
286
|
-
> = ({ method, attribute, ...props }) => {
|
|
287
|
-
switch (method) {
|
|
288
|
-
case 'edit':
|
|
289
|
-
case 'create':
|
|
290
|
-
return (
|
|
291
|
-
<SearchableSelectChipsControl
|
|
292
|
-
attribute={attribute}
|
|
293
|
-
method={method}
|
|
294
|
-
{...props}
|
|
295
|
-
/>
|
|
296
|
-
);
|
|
297
|
-
case 'view':
|
|
298
|
-
return (
|
|
299
|
-
<SearchableSelectChipsControl
|
|
300
|
-
attribute={attribute}
|
|
301
|
-
method={method}
|
|
302
|
-
{...props}
|
|
303
|
-
/>
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
export default RASearchableSelectChips;
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Autocomplete,
|
|
3
|
-
Box,
|
|
4
|
-
CircularProgress,
|
|
5
|
-
InputLabel,
|
|
6
|
-
TextField,
|
|
7
|
-
} from '@mui/material';
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
9
|
-
import { useController, useWatch } from 'react-hook-form';
|
|
10
|
-
import { useGetList } from 'react-admin';
|
|
11
|
-
import TrendingUpRounded from '@mui/icons-material/TrendingUpRounded';
|
|
12
|
-
|
|
13
|
-
const SearchableSelect: React.FC<any> = ({
|
|
14
|
-
name,
|
|
15
|
-
isMultiple = false,
|
|
16
|
-
resource,
|
|
17
|
-
selectLabel,
|
|
18
|
-
title,
|
|
19
|
-
renderText,
|
|
20
|
-
transformData,
|
|
21
|
-
defaultValues = undefined,
|
|
22
|
-
isEmpty = false,
|
|
23
|
-
filter = {},
|
|
24
|
-
}) => {
|
|
25
|
-
const [open, setOpen] = useState(false);
|
|
26
|
-
const [settedInitialValues, setSettedInitialValues] = useState(false);
|
|
27
|
-
const [q, setQ] = useState('');
|
|
28
|
-
const field = useController({ name });
|
|
29
|
-
|
|
30
|
-
const {
|
|
31
|
-
data: resourceData,
|
|
32
|
-
total,
|
|
33
|
-
isLoading,
|
|
34
|
-
error,
|
|
35
|
-
} = useGetList(resource, {
|
|
36
|
-
pagination: { page: 1, perPage: 100 },
|
|
37
|
-
filter: { q, ...filter },
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (resourceData && !settedInitialValues) {
|
|
42
|
-
if (defaultValues) {
|
|
43
|
-
field.field.onChange(defaultValues);
|
|
44
|
-
}
|
|
45
|
-
setSettedInitialValues(true);
|
|
46
|
-
}
|
|
47
|
-
return () => {
|
|
48
|
-
setSettedInitialValues(false);
|
|
49
|
-
};
|
|
50
|
-
}, [resourceData]);
|
|
51
|
-
|
|
52
|
-
//const productIds = useWatch({ name: 'product_ids' });
|
|
53
|
-
|
|
54
|
-
// const selectLabel = "Seleccionar Plantilla";
|
|
55
|
-
|
|
56
|
-
// if(resourceData && selectedDefault?.length > 0)
|
|
57
|
-
// setSelectedDefault(defaultValues?.map(item => resourceData.find(template => template.id === item)));
|
|
58
|
-
|
|
59
|
-
// console.log(field.field.value);
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<>
|
|
63
|
-
<InputLabel>{title}</InputLabel>
|
|
64
|
-
{/*<SearchBar />*/}
|
|
65
|
-
{TrendingUpRounded && (
|
|
66
|
-
<Autocomplete
|
|
67
|
-
multiple={isMultiple}
|
|
68
|
-
loading={isLoading && open}
|
|
69
|
-
sx={{ width: 373 }}
|
|
70
|
-
options={
|
|
71
|
-
!resourceData ? [] : !defaultValues ? resourceData : resourceData
|
|
72
|
-
}
|
|
73
|
-
open={open}
|
|
74
|
-
onOpen={() => setOpen(true)}
|
|
75
|
-
onClose={() => setOpen(false)}
|
|
76
|
-
// defaultValue={field.field.value.map(item => resourceData.find(template => template.id === item))}
|
|
77
|
-
|
|
78
|
-
autoHighlight
|
|
79
|
-
{...(!isEmpty && { value: field.field.value })}
|
|
80
|
-
{...(isEmpty && { renderTags: (value, getTagProps) => <></> })}
|
|
81
|
-
getOptionLabel={(option: any) =>
|
|
82
|
-
renderText ? renderText(option) : option.name
|
|
83
|
-
}
|
|
84
|
-
renderOption={(props, option: any) => (
|
|
85
|
-
<Box
|
|
86
|
-
component='li'
|
|
87
|
-
sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
|
|
88
|
-
{...props}
|
|
89
|
-
>
|
|
90
|
-
{renderText ? renderText(option) : option.name}
|
|
91
|
-
</Box>
|
|
92
|
-
)}
|
|
93
|
-
onChange={(event: any, rawValue) => {
|
|
94
|
-
let newValue = rawValue;
|
|
95
|
-
if (Array.isArray(rawValue)) {
|
|
96
|
-
if (isEmpty) newValue = [...rawValue, ...field.field.value];
|
|
97
|
-
newValue = [...new Map((newValue as any[]).map((v) => [v.id, v])).values()];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (transformData) field.field.onChange(transformData(newValue));
|
|
101
|
-
else field.field.onChange(newValue);
|
|
102
|
-
}}
|
|
103
|
-
renderInput={(params) => (
|
|
104
|
-
<TextField
|
|
105
|
-
{...params}
|
|
106
|
-
label={selectLabel}
|
|
107
|
-
variant='outlined'
|
|
108
|
-
onChange={(ev) => {
|
|
109
|
-
// dont fire API if the user delete or not entered anything
|
|
110
|
-
if (ev.target.value !== '' || ev.target.value !== null) {
|
|
111
|
-
setQ(ev.target.value);
|
|
112
|
-
}
|
|
113
|
-
}}
|
|
114
|
-
onBlur={() => setQ('')}
|
|
115
|
-
slotProps={{
|
|
116
|
-
...params.slotProps,
|
|
117
|
-
|
|
118
|
-
input: {
|
|
119
|
-
...params.slotProps.input,
|
|
120
|
-
autoComplete: 'new-password',
|
|
121
|
-
endAdornment: (
|
|
122
|
-
<>
|
|
123
|
-
{isLoading ? (
|
|
124
|
-
<CircularProgress color='inherit' size={20} />
|
|
125
|
-
) : null}
|
|
126
|
-
{params.slotProps.input.endAdornment}
|
|
127
|
-
</>
|
|
128
|
-
),
|
|
129
|
-
}
|
|
130
|
-
}}
|
|
131
|
-
/>
|
|
132
|
-
)}
|
|
133
|
-
/>
|
|
134
|
-
)}
|
|
135
|
-
</>
|
|
136
|
-
);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export default SearchableSelect;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import Alert from "@mui/material/Alert";
|
|
3
|
-
import Box from "@mui/material/Box";
|
|
4
|
-
import IconButton from "@mui/material/IconButton";
|
|
5
|
-
import Tooltip from "@mui/material/Tooltip";
|
|
6
|
-
import Typography from "@mui/material/Typography";
|
|
7
|
-
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
8
|
-
import CheckIcon from "@mui/icons-material/Check";
|
|
9
|
-
import { useI18nBridge } from "../../contexts/I18nBridgeContext";
|
|
10
|
-
|
|
11
|
-
export interface IApiKeyRevealContentProps {
|
|
12
|
-
/** The plaintext token, shown exactly once. */
|
|
13
|
-
token: string;
|
|
14
|
-
/** Name of the key, for context. */
|
|
15
|
-
name?: string | null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* One-time reveal of a newly issued API key.
|
|
20
|
-
*
|
|
21
|
-
* The plaintext credential is never persisted in recoverable form - only a
|
|
22
|
-
* short display prefix is stored - so this is the single moment the operator
|
|
23
|
-
* can copy it.
|
|
24
|
-
*
|
|
25
|
-
* Designed to be passed as the `content` of the framework dialog via a
|
|
26
|
-
* resource's `createSuccessDialog`, so it inherits the app's dialog chrome
|
|
27
|
-
* rather than introducing a second dialog system:
|
|
28
|
-
*
|
|
29
|
-
* createSuccessDialog: (data) => data?.plain_text_token
|
|
30
|
-
* ? { title: '...', content: <ApiKeyRevealContent token={data.plain_text_token} name={data.name} /> }
|
|
31
|
-
* : null,
|
|
32
|
-
*/
|
|
33
|
-
export const ApiKeyRevealContent: React.FC<IApiKeyRevealContentProps> = ({ token, name }) => {
|
|
34
|
-
// DialogServiceProvider is mounted ABOVE <Admin> in DASHAppProviders, so
|
|
35
|
-
// dialog content renders outside React Admin's i18n context and
|
|
36
|
-
// useTranslate() would silently fall through to the English defaults.
|
|
37
|
-
// The bridge is the supported way to translate from out there - same
|
|
38
|
-
// pattern as AppMaterialMenu.
|
|
39
|
-
const { i18nProvider, locale } = useI18nBridge();
|
|
40
|
-
const [copied, setCopied] = useState(false);
|
|
41
|
-
|
|
42
|
-
const translate = React.useCallback(
|
|
43
|
-
(key: string, options?: any) => {
|
|
44
|
-
if (i18nProvider?.translate) {
|
|
45
|
-
try {
|
|
46
|
-
return i18nProvider.translate(key, options);
|
|
47
|
-
} catch {
|
|
48
|
-
return options?._ ?? key;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return options?._ ?? key;
|
|
52
|
-
},
|
|
53
|
-
// locale is a dependency so the text re-renders on a language switch.
|
|
54
|
-
[i18nProvider, locale]
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const handleCopy = async () => {
|
|
58
|
-
try {
|
|
59
|
-
await navigator.clipboard.writeText(token);
|
|
60
|
-
setCopied(true);
|
|
61
|
-
setTimeout(() => setCopied(false), 2000);
|
|
62
|
-
} catch {
|
|
63
|
-
// Clipboard API unavailable (insecure context or denied permission).
|
|
64
|
-
// The value stays selectable so the operator can still copy it by
|
|
65
|
-
// hand - never leave them without a path to the secret.
|
|
66
|
-
setCopied(false);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<Box>
|
|
72
|
-
<Alert severity="warning" sx={{ mb: 2 }}>
|
|
73
|
-
{translate("serviceAccount.reveal.warning", {
|
|
74
|
-
_: "This is the only time this key will be shown. It cannot be recovered later — if you lose it, you will have to issue a new one.",
|
|
75
|
-
})}
|
|
76
|
-
</Alert>
|
|
77
|
-
|
|
78
|
-
{name ? (
|
|
79
|
-
<Typography variant="body2" sx={{ mb: 1 }}>
|
|
80
|
-
{translate("serviceAccount.reveal.forKey", { _: "Key" })}: <strong>{name}</strong>
|
|
81
|
-
</Typography>
|
|
82
|
-
) : null}
|
|
83
|
-
|
|
84
|
-
<Box
|
|
85
|
-
sx={{
|
|
86
|
-
display: "flex",
|
|
87
|
-
alignItems: "center",
|
|
88
|
-
gap: 1,
|
|
89
|
-
p: 1.5,
|
|
90
|
-
borderRadius: 1,
|
|
91
|
-
border: (theme) => `1px solid ${theme.palette.divider}`,
|
|
92
|
-
bgcolor: (theme) =>
|
|
93
|
-
theme.palette.mode === "dark" ? "rgba(255,255,255,0.04)" : "rgba(0,0,0,0.04)",
|
|
94
|
-
}}
|
|
95
|
-
>
|
|
96
|
-
<Box
|
|
97
|
-
component="code"
|
|
98
|
-
sx={{
|
|
99
|
-
flex: 1,
|
|
100
|
-
fontFamily: "monospace",
|
|
101
|
-
fontSize: "0.875rem",
|
|
102
|
-
wordBreak: "break-all",
|
|
103
|
-
userSelect: "all",
|
|
104
|
-
}}
|
|
105
|
-
>
|
|
106
|
-
{token}
|
|
107
|
-
</Box>
|
|
108
|
-
|
|
109
|
-
<Tooltip
|
|
110
|
-
title={
|
|
111
|
-
copied
|
|
112
|
-
? translate("serviceAccount.reveal.copied", { _: "Copied" })
|
|
113
|
-
: translate("serviceAccount.reveal.copy", { _: "Copy" })
|
|
114
|
-
}
|
|
115
|
-
>
|
|
116
|
-
<IconButton onClick={handleCopy} size="small" aria-label="copy api key">
|
|
117
|
-
{copied ? (
|
|
118
|
-
<CheckIcon color="success" fontSize="small" />
|
|
119
|
-
) : (
|
|
120
|
-
<ContentCopyIcon fontSize="small" />
|
|
121
|
-
)}
|
|
122
|
-
</IconButton>
|
|
123
|
-
</Tooltip>
|
|
124
|
-
</Box>
|
|
125
|
-
</Box>
|
|
126
|
-
);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export default ApiKeyRevealContent;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { useRecordContext, useNotify, useRefresh } from "react-admin";
|
|
3
|
-
import { useAxios } from "dash-axios-hook";
|
|
4
|
-
import Box from "@mui/material/Box";
|
|
5
|
-
import Switch from "@mui/material/Switch";
|
|
6
|
-
import FormControlLabel from "@mui/material/FormControlLabel";
|
|
7
|
-
import CircularProgress from "@mui/material/CircularProgress";
|
|
8
|
-
import { IDashAutoAdminCustomFieldComponent } from "dash-auto-admin";
|
|
9
|
-
import { useI18nBridge } from "../../contexts/I18nBridgeContext";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Enable/disable switch for a service account API key.
|
|
13
|
-
*
|
|
14
|
-
* Deliberately NOT a form field. Status is changed through the dedicated
|
|
15
|
-
* enable/disable endpoints rather than the update payload, for two reasons:
|
|
16
|
-
*
|
|
17
|
-
* - The update contract rejects everything except role_ids, so submitting a
|
|
18
|
-
* status would 422.
|
|
19
|
-
* - Disabling must not rotate the credential. The endpoints flip a flag and
|
|
20
|
-
* leave the token untouched, so re-enabling restores the same key rather
|
|
21
|
-
* than forcing every integration to redeploy a new secret.
|
|
22
|
-
*
|
|
23
|
-
* The switch therefore acts immediately and refreshes, instead of waiting for
|
|
24
|
-
* a form save that would never carry it.
|
|
25
|
-
*/
|
|
26
|
-
const ServiceAccountStatusSwitch: React.FC<IDashAutoAdminCustomFieldComponent> = ({
|
|
27
|
-
resourceConfig,
|
|
28
|
-
}) => {
|
|
29
|
-
const record = useRecordContext();
|
|
30
|
-
const notify = useNotify();
|
|
31
|
-
const refresh = useRefresh();
|
|
32
|
-
const axios = useAxios();
|
|
33
|
-
const { i18nProvider } = useI18nBridge();
|
|
34
|
-
const [loading, setLoading] = useState(false);
|
|
35
|
-
|
|
36
|
-
const translate = React.useCallback(
|
|
37
|
-
(key: string, fallback: string) => {
|
|
38
|
-
try {
|
|
39
|
-
return i18nProvider?.translate(key, { _: fallback }) ?? fallback;
|
|
40
|
-
} catch {
|
|
41
|
-
return fallback;
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
[i18nProvider]
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
if (!record) return null;
|
|
48
|
-
|
|
49
|
-
const isActive = record.status === "active";
|
|
50
|
-
|
|
51
|
-
const handleToggle = async () => {
|
|
52
|
-
setLoading(true);
|
|
53
|
-
try {
|
|
54
|
-
const action = isActive ? "disable" : "enable";
|
|
55
|
-
|
|
56
|
-
await axios.post(`${resourceConfig.model}/${record.id}/${action}`);
|
|
57
|
-
|
|
58
|
-
notify(
|
|
59
|
-
isActive
|
|
60
|
-
? translate("serviceAccount.notify.disabled", "API key disabled")
|
|
61
|
-
: translate("serviceAccount.notify.enabled", "API key enabled"),
|
|
62
|
-
{ type: "success" }
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
refresh();
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error("ServiceAccountStatusSwitch: toggle failed", error);
|
|
68
|
-
notify(
|
|
69
|
-
translate("serviceAccount.notify.toggle_error", "Could not change the key status"),
|
|
70
|
-
{ type: "error" }
|
|
71
|
-
);
|
|
72
|
-
} finally {
|
|
73
|
-
setLoading(false);
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<Box sx={{ display: "flex", alignItems: "center", gap: 1, my: 1 }}>
|
|
79
|
-
<FormControlLabel
|
|
80
|
-
control={
|
|
81
|
-
<Switch
|
|
82
|
-
checked={isActive}
|
|
83
|
-
onChange={handleToggle}
|
|
84
|
-
disabled={loading}
|
|
85
|
-
color="success"
|
|
86
|
-
/>
|
|
87
|
-
}
|
|
88
|
-
label={
|
|
89
|
-
isActive
|
|
90
|
-
? translate("serviceAccount.status.active", "Active")
|
|
91
|
-
: translate("serviceAccount.status.disabled", "Disabled")
|
|
92
|
-
}
|
|
93
|
-
/>
|
|
94
|
-
{loading ? <CircularProgress size={16} /> : null}
|
|
95
|
-
</Box>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export default ServiceAccountStatusSwitch;
|