@hed-hog/core 0.0.368 → 0.0.371
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/LICENSE.md +21 -0
- package/README.md +2 -0
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +10 -7
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/app-command/app-command.module.d.ts +3 -0
- package/dist/app-command/app-command.module.d.ts.map +1 -0
- package/dist/app-command/app-command.module.js +22 -0
- package/dist/app-command/app-command.module.js.map +1 -0
- package/dist/app-command/app-command.registry.d.ts +22 -0
- package/dist/app-command/app-command.registry.d.ts.map +1 -0
- package/dist/{webhook-integration/webhook-command.registry.js → app-command/app-command.registry.js} +6 -6
- package/dist/app-command/app-command.registry.js.map +1 -0
- package/dist/auth/auth.controller.d.ts +2 -2
- package/dist/auth/auth.controller.d.ts.map +1 -1
- package/dist/auth/auth.controller.js +20 -7
- package/dist/auth/auth.controller.js.map +1 -1
- package/dist/auth/auth.service.d.ts +3 -3
- package/dist/auth/auth.service.d.ts.map +1 -1
- package/dist/auth/auth.service.js +10 -36
- package/dist/auth/auth.service.js.map +1 -1
- package/dist/auth/dto/forget.dto.d.ts +1 -0
- package/dist/auth/dto/forget.dto.d.ts.map +1 -1
- package/dist/auth/dto/forget.dto.js +5 -0
- package/dist/auth/dto/forget.dto.js.map +1 -1
- package/dist/auth/guards/auth.guard.d.ts.map +1 -1
- package/dist/auth/guards/auth.guard.js +4 -1
- package/dist/auth/guards/auth.guard.js.map +1 -1
- package/dist/challenge/challenge.service.d.ts +8 -7
- package/dist/challenge/challenge.service.d.ts.map +1 -1
- package/dist/challenge/challenge.service.js +27 -19
- package/dist/challenge/challenge.service.js.map +1 -1
- package/dist/file/dto/upload.dto.d.ts +3 -0
- package/dist/file/dto/upload.dto.d.ts.map +1 -1
- package/dist/file/dto/upload.dto.js +22 -0
- package/dist/file/dto/upload.dto.js.map +1 -1
- package/dist/file/file.controller.d.ts +2 -1
- package/dist/file/file.controller.d.ts.map +1 -1
- package/dist/file/file.controller.js +29 -16
- package/dist/file/file.controller.js.map +1 -1
- package/dist/file/file.service.d.ts +51 -1
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +250 -18
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/image-optimization.service.d.ts +17 -4
- package/dist/file/image-optimization.service.d.ts.map +1 -1
- package/dist/file/image-optimization.service.js +101 -46
- package/dist/file/image-optimization.service.js.map +1 -1
- package/dist/file/provider/s3.provider.d.ts.map +1 -1
- package/dist/file/provider/s3.provider.js +15 -7
- package/dist/file/provider/s3.provider.js.map +1 -1
- package/dist/file/provider/spaces.provider.d.ts.map +1 -1
- package/dist/file/provider/spaces.provider.js +18 -8
- package/dist/file/provider/spaces.provider.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/integration/services/event-subscriber.registry.d.ts +5 -0
- package/dist/integration/services/event-subscriber.registry.d.ts.map +1 -1
- package/dist/integration/services/event-subscriber.registry.js +15 -0
- package/dist/integration/services/event-subscriber.registry.js.map +1 -1
- package/dist/integration/services/outbox.processor.d.ts.map +1 -1
- package/dist/integration/services/outbox.processor.js +2 -4
- package/dist/integration/services/outbox.processor.js.map +1 -1
- package/dist/integration/services/outbox.service.d.ts +4 -2
- package/dist/integration/services/outbox.service.d.ts.map +1 -1
- package/dist/integration/services/outbox.service.js +26 -15
- package/dist/integration/services/outbox.service.js.map +1 -1
- package/dist/integration-profile/integration-credential-crypto.service.d.ts +43 -0
- package/dist/integration-profile/integration-credential-crypto.service.d.ts.map +1 -0
- package/dist/integration-profile/integration-credential-crypto.service.js +142 -0
- package/dist/integration-profile/integration-credential-crypto.service.js.map +1 -0
- package/dist/integration-profile/integration-profile.controller.d.ts +6 -7
- package/dist/integration-profile/integration-profile.controller.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.controller.js +4 -3
- package/dist/integration-profile/integration-profile.controller.js.map +1 -1
- package/dist/integration-profile/integration-profile.module.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.module.js +5 -2
- package/dist/integration-profile/integration-profile.module.js.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.d.ts +16 -0
- package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.secrets.js +56 -0
- package/dist/integration-profile/integration-profile.secrets.js.map +1 -0
- package/dist/integration-profile/integration-profile.service.d.ts +125 -8
- package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.service.js +257 -68
- package/dist/integration-profile/integration-profile.service.js.map +1 -1
- package/dist/integration-profile/integration-profile.utils.d.ts +17 -0
- package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.utils.js +31 -0
- package/dist/integration-profile/integration-profile.utils.js.map +1 -1
- package/dist/language/en.json +178 -0
- package/dist/language/pt.json +178 -0
- package/dist/mail/mail.controller.d.ts.map +1 -1
- package/dist/mail/mail.controller.js +5 -28
- package/dist/mail/mail.controller.js.map +1 -1
- package/dist/mail/mail.module.js +18 -18
- package/dist/mail/mail.module.js.map +1 -1
- package/dist/mail/mail.service.d.ts +13 -2
- package/dist/mail/mail.service.d.ts.map +1 -1
- package/dist/mail/mail.service.js +25 -15
- package/dist/mail/mail.service.js.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.js +6 -5
- package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
- package/dist/oauth/providers/facebook.provider.js +5 -5
- package/dist/oauth/providers/facebook.provider.js.map +1 -1
- package/dist/oauth/providers/github.provider.js +5 -5
- package/dist/oauth/providers/github.provider.js.map +1 -1
- package/dist/oauth/providers/google.provider.js +5 -5
- package/dist/oauth/providers/google.provider.js.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.js +5 -5
- package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
- package/dist/oauth/providers/microsoft.provider.js +5 -5
- package/dist/oauth/providers/microsoft.provider.js.map +1 -1
- package/dist/pdf/pdf.service.d.ts +4 -0
- package/dist/pdf/pdf.service.d.ts.map +1 -1
- package/dist/pdf/pdf.service.js +16 -9
- package/dist/pdf/pdf.service.js.map +1 -1
- package/dist/profile/profile.controller.d.ts +7 -7
- package/dist/profile/profile.controller.d.ts.map +1 -1
- package/dist/profile/profile.controller.js +28 -21
- package/dist/profile/profile.controller.js.map +1 -1
- package/dist/profile/profile.service.d.ts +7 -7
- package/dist/profile/profile.service.d.ts.map +1 -1
- package/dist/profile/profile.service.js +21 -25
- package/dist/profile/profile.service.js.map +1 -1
- package/dist/setting/setting.service.d.ts +1 -0
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +15 -2
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/token/token.service.d.ts.map +1 -1
- package/dist/token/token.service.js +2 -1
- package/dist/token/token.service.js.map +1 -1
- package/dist/user/user.controller.d.ts +9 -0
- package/dist/user/user.controller.d.ts.map +1 -1
- package/dist/user/user.controller.js +13 -0
- package/dist/user/user.controller.js.map +1 -1
- package/dist/user/user.service.d.ts +7 -0
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +19 -0
- package/dist/user/user.service.js.map +1 -1
- package/dist/utils/webauthn-origin.d.ts +11 -0
- package/dist/utils/webauthn-origin.d.ts.map +1 -0
- package/dist/utils/webauthn-origin.js +37 -0
- package/dist/utils/webauthn-origin.js.map +1 -0
- package/dist/webhook-integration/webhook-integration.controller.d.ts +13 -0
- package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.controller.js +29 -0
- package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.module.js +3 -3
- package/dist/webhook-integration/webhook-integration.module.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.d.ts +18 -2
- package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.js +110 -6
- package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
- package/hedhog/data/integration_event_catalog.yaml +118 -118
- package/hedhog/data/integration_provider.yaml +9 -0
- package/hedhog/data/integration_type.yaml +6 -0
- package/hedhog/data/menu.yaml +6 -0
- package/hedhog/data/role.yaml +7 -0
- package/hedhog/data/route.yaml +192 -207
- package/hedhog/data/setting_group.yaml +119 -13
- package/hedhog/frontend/app/access-log/page.tsx.ejs +35 -3
- package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +36 -3
- package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +39 -4
- package/hedhog/frontend/app/account/components/tokens.tsx.ejs +39 -4
- package/hedhog/frontend/app/ai_agent/page.tsx.ejs +35 -2
- package/hedhog/frontend/app/configurations/[slug]/components/byte-size-input.tsx.ejs +160 -0
- package/hedhog/frontend/app/configurations/[slug]/components/duration-input.tsx.ejs +157 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +244 -63
- package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +33 -1
- package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +35 -3
- package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +36 -4
- package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +35 -3
- package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +36 -4
- package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +35 -3
- package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +141 -29
- package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +118 -11
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +37 -4
- package/hedhog/frontend/app/menu/page.tsx.ejs +34 -2
- package/hedhog/frontend/app/preferences/page.tsx.ejs +77 -0
- package/hedhog/frontend/app/roles/menus.tsx.ejs +35 -3
- package/hedhog/frontend/app/roles/page.tsx.ejs +34 -2
- package/hedhog/frontend/app/roles/routes.tsx.ejs +36 -4
- package/hedhog/frontend/app/roles/users.tsx.ejs +36 -4
- package/hedhog/frontend/app/routes/page.tsx.ejs +34 -2
- package/hedhog/frontend/app/setting-list/page.tsx.ejs +34 -2
- package/hedhog/frontend/app/users/page.tsx.ejs +51 -21
- package/hedhog/frontend/messages/en.json +69 -4
- package/hedhog/frontend/messages/pt.json +69 -4
- package/hedhog/table/event_webhook.yaml +55 -55
- package/hedhog/table/event_webhook_delivery_log.yaml +66 -66
- package/hedhog/table/event_webhook_event.yaml +26 -26
- package/hedhog/table/integration_event_catalog.yaml +41 -41
- package/hedhog/table/mcp_conversation.yaml +12 -12
- package/hedhog/table/mcp_conversation_message.yaml +23 -23
- package/hedhog/table/mcp_tool_call_log.yaml +22 -22
- package/hedhog/table/route.yaml +33 -33
- package/hedhog/table/setting.yaml +2 -0
- package/hedhog/table/webhook_call_log.yaml +3 -0
- package/hedhog/table/webhook_integration.yaml +43 -43
- package/package.json +9 -4
- package/src/ai/ai.service.ts +9 -6
- package/src/app-command/app-command.module.ts +9 -0
- package/src/{webhook-integration/webhook-command.registry.ts → app-command/app-command.registry.ts} +9 -9
- package/src/auth/auth.controller.ts +20 -4
- package/src/auth/auth.service.ts +10 -36
- package/src/auth/dto/forget.dto.ts +5 -1
- package/src/auth/guards/auth.guard.ts +4 -1
- package/src/challenge/challenge.service.ts +30 -19
- package/src/file/dto/upload.dto.ts +25 -1
- package/src/file/file.controller.ts +31 -18
- package/src/file/file.service.ts +341 -16
- package/src/file/image-optimization.service.ts +111 -46
- package/src/file/provider/s3.provider.ts +16 -7
- package/src/file/provider/spaces.provider.ts +15 -5
- package/src/index.ts +4 -1
- package/src/integration/services/event-subscriber.registry.ts +15 -0
- package/src/integration/services/outbox.processor.ts +2 -5
- package/src/integration/services/outbox.service.ts +35 -17
- package/src/integration/types/event.types.ts +4 -4
- package/src/integration-profile/integration-credential-crypto.service.ts +146 -0
- package/src/integration-profile/integration-profile.controller.ts +2 -0
- package/src/integration-profile/integration-profile.module.ts +5 -2
- package/src/integration-profile/integration-profile.secrets.ts +51 -0
- package/src/integration-profile/integration-profile.service.ts +335 -54
- package/src/integration-profile/integration-profile.utils.ts +56 -0
- package/src/language/en.json +5 -1
- package/src/language/pt.json +5 -1
- package/src/mail/mail.controller.ts +5 -29
- package/src/mail/mail.module.ts +5 -5
- package/src/mail/mail.service.ts +37 -13
- package/src/mcp/decorators/mcp-tool.decorator.ts +7 -7
- package/src/mcp/guards/mcp-permission.guard.ts +51 -51
- package/src/mcp/interfaces/mcp-tool-definition.interface.ts +6 -6
- package/src/mcp/mcp-server.service.ts +87 -87
- package/src/mcp/types/mcp-context.type.ts +6 -6
- package/src/mcp-chat/dto/create-conversation.dto.ts +7 -7
- package/src/mcp-chat/dto/send-message.dto.ts +7 -7
- package/src/mcp-chat/mcp-chat.service.ts +5 -5
- package/src/notification/events/notification-stale-progress-check.event.ts +5 -5
- package/src/oauth/oauth-callback-coordinator.service.spec.ts +159 -0
- package/src/oauth/providers/facebook.provider.ts +3 -3
- package/src/oauth/providers/github.provider.ts +3 -3
- package/src/oauth/providers/google.provider.ts +3 -3
- package/src/oauth/providers/microsoft-entra-id.provider.ts +3 -3
- package/src/oauth/providers/microsoft.provider.ts +3 -3
- package/src/pdf/pdf.service.ts +19 -6
- package/src/profile/profile.controller.ts +21 -14
- package/src/profile/profile.service.ts +23 -20
- package/src/route/dto/create.dto.ts +32 -32
- package/src/route/dto/update.dto.ts +31 -31
- package/src/security/security.service.spec.ts +222 -0
- package/src/setting/setting.service.ts +15 -2
- package/src/token/token.service.ts +2 -1
- package/src/user/user.controller.ts +26 -16
- package/src/user/user.service.ts +25 -0
- package/src/utils/webauthn-origin.ts +38 -0
- package/src/webhook-integration/integration-event-catalog.controller.ts +50 -50
- package/src/webhook-integration/integration-event-catalog.service.ts +117 -117
- package/src/webhook-integration/webhook-integration.controller.ts +23 -0
- package/src/webhook-integration/webhook-integration.module.ts +3 -3
- package/src/webhook-integration/webhook-integration.service.ts +115 -5
- package/dist/webhook-integration/webhook-command.registry.d.ts +0 -22
- package/dist/webhook-integration/webhook-command.registry.d.ts.map +0 -1
- package/dist/webhook-integration/webhook-command.registry.js.map +0 -1
- package/src/menu/menu.service.spec.ts +0 -247
- package/src/route/route.service.spec.ts +0 -300
- package/src/screen/screen.service.spec.ts +0 -298
- package/src/user/user.service.spec.ts +0 -294
|
@@ -16,6 +16,9 @@ import {
|
|
|
16
16
|
SelectValue,
|
|
17
17
|
} from '@/components/ui/select';
|
|
18
18
|
import { Switch } from '@/components/ui/switch';
|
|
19
|
+
import { TagsInput } from '@/components/ui/tags-input';
|
|
20
|
+
import { ByteSizeInput } from './byte-size-input';
|
|
21
|
+
import { DurationInput } from './duration-input';
|
|
19
22
|
import { revalidateSystemIcon } from '@/lib/revalidate-icon';
|
|
20
23
|
import { cn } from '@/lib/utils';
|
|
21
24
|
import {
|
|
@@ -88,6 +91,7 @@ function getLocalizedIntegrationName(
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
const MAIL_INTEGRATION_PROFILE_SETTING_SLUG = 'mail-integration-profile-id';
|
|
94
|
+
const SCALING_INFRA_PROFILE_SETTING_SLUG = 'scaling.video.integration_profile_id';
|
|
91
95
|
const COMMERCE_PAYMENT_PROFILE_SETTING_SLUG =
|
|
92
96
|
'commerce-default-payment-profile-id';
|
|
93
97
|
const DAILY_REPORT_EMAIL_INTEGRATION_SETTING_SLUG =
|
|
@@ -106,9 +110,16 @@ const OAUTH_PROFILE_SLUG_TO_PROVIDER: Record<string, string> = {
|
|
|
106
110
|
'oauth-microsoft-profile-id': 'microsoft-oauth',
|
|
107
111
|
'oauth-microsoft-entra-id-profile-id': 'microsoft-entra-id-oauth',
|
|
108
112
|
};
|
|
109
|
-
|
|
110
|
-
|
|
113
|
+
// Settings cujo valor é o SLUG de um integration_profile. O picker continua sendo
|
|
114
|
+
// selecionado/exibido pelo nome; apenas o valor persistido é o slug.
|
|
115
|
+
const ALL_INTEGRATION_PROFILE_SETTING_SLUGS = [
|
|
116
|
+
MAIL_INTEGRATION_PROFILE_SETTING_SLUG,
|
|
117
|
+
SCALING_INFRA_PROFILE_SETTING_SLUG,
|
|
111
118
|
COMMERCE_PAYMENT_PROFILE_SETTING_SLUG,
|
|
119
|
+
DAILY_REPORT_EMAIL_INTEGRATION_SETTING_SLUG,
|
|
120
|
+
DAILY_REPORT_WHATSAPP_INTEGRATION_SETTING_SLUG,
|
|
121
|
+
'file-storage-profile-id',
|
|
122
|
+
'lms-bulk-upload-storage-profile-id',
|
|
112
123
|
...AI_PROFILE_SETTING_SLUGS,
|
|
113
124
|
...Object.keys(OAUTH_PROFILE_SLUG_TO_PROVIDER),
|
|
114
125
|
];
|
|
@@ -199,6 +210,11 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
199
210
|
const [storageProfileEditingId, setStorageProfileEditingId] = useState<
|
|
200
211
|
number | null
|
|
201
212
|
>(null);
|
|
213
|
+
// Id resolvido a partir do slug salvo (a setting guarda o slug; o botão "editar"
|
|
214
|
+
// e o sheet precisam do id numérico do perfil).
|
|
215
|
+
const [resolvedProfileId, setResolvedProfileId] = useState<number | null>(
|
|
216
|
+
null
|
|
217
|
+
);
|
|
202
218
|
const [showSecretValue, setShowSecretValue] = useState(false);
|
|
203
219
|
const [isUploading, setIsUploading] = useState(false);
|
|
204
220
|
const debounceTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
|
@@ -261,21 +277,24 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
261
277
|
}, [localValue]);
|
|
262
278
|
|
|
263
279
|
useEffect(() => {
|
|
264
|
-
if (!
|
|
280
|
+
if (!ALL_INTEGRATION_PROFILE_SETTING_SLUGS.includes(setting.slug)) {
|
|
265
281
|
setStorageProfileSelectedLabel('');
|
|
282
|
+
setResolvedProfileId(null);
|
|
266
283
|
return;
|
|
267
284
|
}
|
|
268
285
|
|
|
269
|
-
const
|
|
270
|
-
if (!
|
|
286
|
+
const profileSlug = String(localValue ?? '').trim();
|
|
287
|
+
if (!profileSlug) {
|
|
271
288
|
setStorageProfileSelectedLabel('');
|
|
289
|
+
setResolvedProfileId(null);
|
|
272
290
|
return;
|
|
273
291
|
}
|
|
274
292
|
|
|
275
293
|
let isCurrent = true;
|
|
276
294
|
|
|
277
|
-
|
|
278
|
-
|
|
295
|
+
const qs = new URLSearchParams({ slug: profileSlug, pageSize: '1' });
|
|
296
|
+
request<ApiPaginated<IntegrationProfileOption>>({
|
|
297
|
+
url: `/integration-profile?${qs}`,
|
|
279
298
|
method: 'GET',
|
|
280
299
|
})
|
|
281
300
|
.then((response) => {
|
|
@@ -283,11 +302,14 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
283
302
|
return;
|
|
284
303
|
}
|
|
285
304
|
|
|
286
|
-
|
|
305
|
+
const profile = response.data?.data?.[0] ?? null;
|
|
306
|
+
setStorageProfileSelectedLabel(profile?.name ?? '');
|
|
307
|
+
setResolvedProfileId(profile?.id ?? null);
|
|
287
308
|
})
|
|
288
309
|
.catch(() => {
|
|
289
310
|
if (isCurrent) {
|
|
290
311
|
setStorageProfileSelectedLabel('');
|
|
312
|
+
setResolvedProfileId(null);
|
|
291
313
|
}
|
|
292
314
|
});
|
|
293
315
|
|
|
@@ -375,6 +397,36 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
375
397
|
/>
|
|
376
398
|
);
|
|
377
399
|
|
|
400
|
+
case SettingComponentEnum.INPUT_DURATION:
|
|
401
|
+
isTextInputRef.current = true; // reaproveita o debounce de 500ms existente
|
|
402
|
+
return (
|
|
403
|
+
<DurationInput
|
|
404
|
+
value={
|
|
405
|
+
typeof parsedValue === 'number'
|
|
406
|
+
? parsedValue
|
|
407
|
+
: parseFloat(parsedValue) || 0
|
|
408
|
+
}
|
|
409
|
+
onChange={(seconds) => handleChangeValue(formatValue(seconds))}
|
|
410
|
+
persistKey={setting.slug}
|
|
411
|
+
className={cn(className, 'w-full min-w-0 bg-background md:min-w-50')}
|
|
412
|
+
/>
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
case SettingComponentEnum.INPUT_BYTES:
|
|
416
|
+
isTextInputRef.current = true; // reaproveita o debounce de 500ms existente
|
|
417
|
+
return (
|
|
418
|
+
<ByteSizeInput
|
|
419
|
+
value={
|
|
420
|
+
typeof parsedValue === 'number'
|
|
421
|
+
? parsedValue
|
|
422
|
+
: parseFloat(parsedValue) || 0
|
|
423
|
+
}
|
|
424
|
+
onChange={(bytes) => handleChangeValue(formatValue(bytes))}
|
|
425
|
+
persistKey={setting.slug}
|
|
426
|
+
className={cn(className, 'w-full min-w-0 bg-background md:min-w-50')}
|
|
427
|
+
/>
|
|
428
|
+
);
|
|
429
|
+
|
|
378
430
|
case SettingComponentEnum.INPUT_SECRET:
|
|
379
431
|
isTextInputRef.current = true;
|
|
380
432
|
return (
|
|
@@ -503,6 +555,17 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
503
555
|
</div>
|
|
504
556
|
);
|
|
505
557
|
|
|
558
|
+
case SettingComponentEnum.INPUT_TAGS: {
|
|
559
|
+
const tagsValue: string[] = Array.isArray(parsedValue) ? parsedValue : [];
|
|
560
|
+
return (
|
|
561
|
+
<TagsInput
|
|
562
|
+
value={tagsValue}
|
|
563
|
+
onChange={(val) => handleChangeValue(formatValue(val), true)}
|
|
564
|
+
className={cn(className, 'w-full min-w-0 bg-background md:min-w-50')}
|
|
565
|
+
/>
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
|
|
506
569
|
case SettingComponentEnum.SWITCH:
|
|
507
570
|
return (
|
|
508
571
|
<Switch
|
|
@@ -664,12 +727,15 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
664
727
|
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
665
728
|
placeholder={t('selectStorageProfile')}
|
|
666
729
|
emptyStateDescription={t('storageProfileEmptyState')}
|
|
667
|
-
value={parsedValue
|
|
668
|
-
onChange={(
|
|
730
|
+
value={parsedValue || null}
|
|
731
|
+
onChange={(slug, option) => {
|
|
669
732
|
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
670
|
-
|
|
733
|
+
setResolvedProfileId(
|
|
734
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
735
|
+
);
|
|
736
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
671
737
|
}}
|
|
672
|
-
valueType="
|
|
738
|
+
valueType="string"
|
|
673
739
|
initialSelectedLabel={storageProfileSelectedLabel}
|
|
674
740
|
showCreateButton={false}
|
|
675
741
|
clearable={false}
|
|
@@ -695,7 +761,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
695
761
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
696
762
|
};
|
|
697
763
|
}}
|
|
698
|
-
getOptionValue={(opt) => opt.
|
|
764
|
+
getOptionValue={(opt) => opt.slug}
|
|
699
765
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
700
766
|
getOptionDescription={(opt) => {
|
|
701
767
|
const providerSlug = String(
|
|
@@ -718,12 +784,10 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
718
784
|
size="icon"
|
|
719
785
|
className="h-10 w-10 shrink-0"
|
|
720
786
|
onClick={() => {
|
|
721
|
-
setStorageProfileEditingId(
|
|
722
|
-
parsedValue ? Number(parsedValue) : null
|
|
723
|
-
);
|
|
787
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
724
788
|
setIsStorageProfileSheetOpen(true);
|
|
725
789
|
}}
|
|
726
|
-
disabled={!
|
|
790
|
+
disabled={!resolvedProfileId}
|
|
727
791
|
aria-label="Editar perfil de armazenamento"
|
|
728
792
|
title="Editar perfil de armazenamento"
|
|
729
793
|
>
|
|
@@ -759,7 +823,8 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
759
823
|
lockedTypeSlug="storage"
|
|
760
824
|
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
761
825
|
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
762
|
-
|
|
826
|
+
setResolvedProfileId(profile.id ?? null);
|
|
827
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
763
828
|
}}
|
|
764
829
|
/>
|
|
765
830
|
</>
|
|
@@ -773,12 +838,15 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
773
838
|
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
774
839
|
placeholder={t('selectAiProfile')}
|
|
775
840
|
emptyStateDescription={t('aiProfileEmptyState')}
|
|
776
|
-
value={parsedValue
|
|
777
|
-
onChange={(
|
|
841
|
+
value={parsedValue || null}
|
|
842
|
+
onChange={(slug, option) => {
|
|
778
843
|
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
779
|
-
|
|
844
|
+
setResolvedProfileId(
|
|
845
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
846
|
+
);
|
|
847
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
780
848
|
}}
|
|
781
|
-
valueType="
|
|
849
|
+
valueType="string"
|
|
782
850
|
initialSelectedLabel={storageProfileSelectedLabel}
|
|
783
851
|
showCreateButton={false}
|
|
784
852
|
clearable={false}
|
|
@@ -803,7 +871,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
803
871
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
804
872
|
};
|
|
805
873
|
}}
|
|
806
|
-
getOptionValue={(opt) => opt.
|
|
874
|
+
getOptionValue={(opt) => opt.slug}
|
|
807
875
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
808
876
|
getOptionDescription={(opt) => {
|
|
809
877
|
const providerSlug = String(
|
|
@@ -826,12 +894,10 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
826
894
|
size="icon"
|
|
827
895
|
className="h-10 w-10 shrink-0"
|
|
828
896
|
onClick={() => {
|
|
829
|
-
setStorageProfileEditingId(
|
|
830
|
-
parsedValue ? Number(parsedValue) : null
|
|
831
|
-
);
|
|
897
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
832
898
|
setIsStorageProfileSheetOpen(true);
|
|
833
899
|
}}
|
|
834
|
-
disabled={!
|
|
900
|
+
disabled={!resolvedProfileId}
|
|
835
901
|
aria-label="Editar perfil de IA"
|
|
836
902
|
title="Editar perfil de IA"
|
|
837
903
|
>
|
|
@@ -865,7 +931,8 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
865
931
|
lockedTypeSlug="ai"
|
|
866
932
|
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
867
933
|
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
868
|
-
|
|
934
|
+
setResolvedProfileId(profile.id ?? null);
|
|
935
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
869
936
|
}}
|
|
870
937
|
/>
|
|
871
938
|
</>
|
|
@@ -880,12 +947,15 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
880
947
|
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
881
948
|
placeholder={t('selectOAuthProfile')}
|
|
882
949
|
emptyStateDescription={t('oauthProfileEmptyState')}
|
|
883
|
-
value={parsedValue
|
|
884
|
-
onChange={(
|
|
950
|
+
value={parsedValue || null}
|
|
951
|
+
onChange={(slug, option) => {
|
|
885
952
|
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
886
|
-
|
|
953
|
+
setResolvedProfileId(
|
|
954
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
955
|
+
);
|
|
956
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
887
957
|
}}
|
|
888
|
-
valueType="
|
|
958
|
+
valueType="string"
|
|
889
959
|
initialSelectedLabel={storageProfileSelectedLabel}
|
|
890
960
|
showCreateButton={false}
|
|
891
961
|
clearable={false}
|
|
@@ -910,7 +980,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
910
980
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
911
981
|
};
|
|
912
982
|
}}
|
|
913
|
-
getOptionValue={(opt) => opt.
|
|
983
|
+
getOptionValue={(opt) => opt.slug}
|
|
914
984
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
915
985
|
getOptionDescription={(opt) => {
|
|
916
986
|
const providerSlug = String(
|
|
@@ -933,12 +1003,10 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
933
1003
|
size="icon"
|
|
934
1004
|
className="h-10 w-10 shrink-0"
|
|
935
1005
|
onClick={() => {
|
|
936
|
-
setStorageProfileEditingId(
|
|
937
|
-
parsedValue ? Number(parsedValue) : null
|
|
938
|
-
);
|
|
1006
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
939
1007
|
setIsStorageProfileSheetOpen(true);
|
|
940
1008
|
}}
|
|
941
|
-
disabled={!
|
|
1009
|
+
disabled={!resolvedProfileId}
|
|
942
1010
|
aria-label="Editar perfil OAuth"
|
|
943
1011
|
title="Editar perfil OAuth"
|
|
944
1012
|
>
|
|
@@ -972,7 +1040,8 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
972
1040
|
lockedTypeSlug="oauth"
|
|
973
1041
|
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
974
1042
|
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
975
|
-
|
|
1043
|
+
setResolvedProfileId(profile.id ?? null);
|
|
1044
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
976
1045
|
}}
|
|
977
1046
|
/>
|
|
978
1047
|
</>
|
|
@@ -986,12 +1055,15 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
986
1055
|
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
987
1056
|
placeholder={t('selectPaymentProfile')}
|
|
988
1057
|
emptyStateDescription={t('paymentProfileEmptyState')}
|
|
989
|
-
value={parsedValue
|
|
990
|
-
onChange={(
|
|
1058
|
+
value={parsedValue || null}
|
|
1059
|
+
onChange={(slug, option) => {
|
|
991
1060
|
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
992
|
-
|
|
1061
|
+
setResolvedProfileId(
|
|
1062
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
1063
|
+
);
|
|
1064
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
993
1065
|
}}
|
|
994
|
-
valueType="
|
|
1066
|
+
valueType="string"
|
|
995
1067
|
initialSelectedLabel={storageProfileSelectedLabel}
|
|
996
1068
|
showCreateButton={false}
|
|
997
1069
|
clearable={false}
|
|
@@ -1016,7 +1088,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1016
1088
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
1017
1089
|
};
|
|
1018
1090
|
}}
|
|
1019
|
-
getOptionValue={(opt) => opt.
|
|
1091
|
+
getOptionValue={(opt) => opt.slug}
|
|
1020
1092
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
1021
1093
|
getOptionDescription={(opt) => {
|
|
1022
1094
|
const providerSlug = String(
|
|
@@ -1039,12 +1111,10 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1039
1111
|
size="icon"
|
|
1040
1112
|
className="h-10 w-10 shrink-0"
|
|
1041
1113
|
onClick={() => {
|
|
1042
|
-
setStorageProfileEditingId(
|
|
1043
|
-
parsedValue ? Number(parsedValue) : null
|
|
1044
|
-
);
|
|
1114
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
1045
1115
|
setIsStorageProfileSheetOpen(true);
|
|
1046
1116
|
}}
|
|
1047
|
-
disabled={!
|
|
1117
|
+
disabled={!resolvedProfileId}
|
|
1048
1118
|
aria-label="Editar perfil de pagamento"
|
|
1049
1119
|
title="Editar perfil de pagamento"
|
|
1050
1120
|
>
|
|
@@ -1078,7 +1148,116 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1078
1148
|
lockedTypeSlug="payment"
|
|
1079
1149
|
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
1080
1150
|
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
1081
|
-
|
|
1151
|
+
setResolvedProfileId(profile.id ?? null);
|
|
1152
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
1153
|
+
}}
|
|
1154
|
+
/>
|
|
1155
|
+
</>
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
if (setting.slug === SCALING_INFRA_PROFILE_SETTING_SLUG) {
|
|
1160
|
+
return (
|
|
1161
|
+
<>
|
|
1162
|
+
<div className="flex w-full min-w-0 items-center gap-2 md:max-w-72">
|
|
1163
|
+
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
1164
|
+
placeholder={t('selectInfraProfile')}
|
|
1165
|
+
emptyStateDescription={t('infraProfileEmptyState')}
|
|
1166
|
+
value={parsedValue || null}
|
|
1167
|
+
onChange={(slug, option) => {
|
|
1168
|
+
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
1169
|
+
setResolvedProfileId(
|
|
1170
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
1171
|
+
);
|
|
1172
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
1173
|
+
}}
|
|
1174
|
+
valueType="string"
|
|
1175
|
+
initialSelectedLabel={storageProfileSelectedLabel}
|
|
1176
|
+
showCreateButton={false}
|
|
1177
|
+
clearable
|
|
1178
|
+
loadOptions={async ({ page, pageSize, search }) => {
|
|
1179
|
+
const qs = new URLSearchParams({
|
|
1180
|
+
page: String(page),
|
|
1181
|
+
pageSize: String(pageSize),
|
|
1182
|
+
typeSlug: 'infrastructure',
|
|
1183
|
+
});
|
|
1184
|
+
if (search) qs.set('search', search);
|
|
1185
|
+
const response = await request<
|
|
1186
|
+
ApiPaginated<
|
|
1187
|
+
IntegrationProfileOption & Record<string, unknown>
|
|
1188
|
+
>
|
|
1189
|
+
>({
|
|
1190
|
+
url: `/integration-profile?${qs}`,
|
|
1191
|
+
method: 'GET',
|
|
1192
|
+
});
|
|
1193
|
+
const paged = response.data;
|
|
1194
|
+
return {
|
|
1195
|
+
items: paged?.data ?? [],
|
|
1196
|
+
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
1197
|
+
};
|
|
1198
|
+
}}
|
|
1199
|
+
getOptionValue={(opt) => opt.slug}
|
|
1200
|
+
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
1201
|
+
getOptionDescription={(opt) => {
|
|
1202
|
+
const providerSlug = String(
|
|
1203
|
+
opt.integration_provider?.slug ?? ''
|
|
1204
|
+
);
|
|
1205
|
+
const providerName = getLocalizedIntegrationName(
|
|
1206
|
+
opt.integration_provider?.integration_provider_locale,
|
|
1207
|
+
currentLocaleCode
|
|
1208
|
+
);
|
|
1209
|
+
return [providerName || providerSlug, opt.slug]
|
|
1210
|
+
.filter(Boolean)
|
|
1211
|
+
.join(' • ');
|
|
1212
|
+
}}
|
|
1213
|
+
className={cn('flex-1 min-w-0', className)}
|
|
1214
|
+
/>
|
|
1215
|
+
|
|
1216
|
+
<Button
|
|
1217
|
+
type="button"
|
|
1218
|
+
variant="outline"
|
|
1219
|
+
size="icon"
|
|
1220
|
+
className="h-10 w-10 shrink-0"
|
|
1221
|
+
onClick={() => {
|
|
1222
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
1223
|
+
setIsStorageProfileSheetOpen(true);
|
|
1224
|
+
}}
|
|
1225
|
+
disabled={!resolvedProfileId}
|
|
1226
|
+
aria-label="Editar perfil de infraestrutura"
|
|
1227
|
+
title="Editar perfil de infraestrutura"
|
|
1228
|
+
>
|
|
1229
|
+
<Pencil className="h-4 w-4" />
|
|
1230
|
+
</Button>
|
|
1231
|
+
|
|
1232
|
+
<Button
|
|
1233
|
+
type="button"
|
|
1234
|
+
variant="outline"
|
|
1235
|
+
size="icon"
|
|
1236
|
+
className="h-10 w-10 shrink-0"
|
|
1237
|
+
onClick={() => {
|
|
1238
|
+
setStorageProfileEditingId(null);
|
|
1239
|
+
setIsStorageProfileSheetOpen(true);
|
|
1240
|
+
}}
|
|
1241
|
+
aria-label="Criar perfil de infraestrutura"
|
|
1242
|
+
title="Criar perfil de infraestrutura"
|
|
1243
|
+
>
|
|
1244
|
+
<Plus className="h-4 w-4" />
|
|
1245
|
+
</Button>
|
|
1246
|
+
</div>
|
|
1247
|
+
|
|
1248
|
+
<IntegrationProfileSheet
|
|
1249
|
+
open={isStorageProfileSheetOpen}
|
|
1250
|
+
onOpenChange={(nextOpen) => {
|
|
1251
|
+
setIsStorageProfileSheetOpen(nextOpen);
|
|
1252
|
+
if (!nextOpen) setStorageProfileEditingId(null);
|
|
1253
|
+
}}
|
|
1254
|
+
profileId={storageProfileEditingId}
|
|
1255
|
+
initialTypeSlug="infrastructure"
|
|
1256
|
+
lockedTypeSlug="infrastructure"
|
|
1257
|
+
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
1258
|
+
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
1259
|
+
setResolvedProfileId(profile.id ?? null);
|
|
1260
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
1082
1261
|
}}
|
|
1083
1262
|
/>
|
|
1084
1263
|
</>
|
|
@@ -1092,12 +1271,15 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1092
1271
|
<EntityPicker<IntegrationProfileOption & Record<string, unknown>>
|
|
1093
1272
|
placeholder={t('selectMailProfile')}
|
|
1094
1273
|
emptyStateDescription={t('mailProfileEmptyState')}
|
|
1095
|
-
value={parsedValue
|
|
1096
|
-
onChange={(
|
|
1274
|
+
value={parsedValue || null}
|
|
1275
|
+
onChange={(slug, option) => {
|
|
1097
1276
|
setStorageProfileSelectedLabel(option?.name ?? '');
|
|
1098
|
-
|
|
1277
|
+
setResolvedProfileId(
|
|
1278
|
+
option ? Number((option as { id?: number }).id) || null : null
|
|
1279
|
+
);
|
|
1280
|
+
handleChangeValue(slug != null ? String(slug) : '', true);
|
|
1099
1281
|
}}
|
|
1100
|
-
valueType="
|
|
1282
|
+
valueType="string"
|
|
1101
1283
|
initialSelectedLabel={storageProfileSelectedLabel}
|
|
1102
1284
|
showCreateButton={false}
|
|
1103
1285
|
clearable={false}
|
|
@@ -1122,7 +1304,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1122
1304
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
1123
1305
|
};
|
|
1124
1306
|
}}
|
|
1125
|
-
getOptionValue={(opt) => opt.
|
|
1307
|
+
getOptionValue={(opt) => opt.slug}
|
|
1126
1308
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
1127
1309
|
getOptionDescription={(opt) => {
|
|
1128
1310
|
const providerSlug = String(
|
|
@@ -1145,12 +1327,10 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1145
1327
|
size="icon"
|
|
1146
1328
|
className="h-10 w-10 shrink-0"
|
|
1147
1329
|
onClick={() => {
|
|
1148
|
-
setStorageProfileEditingId(
|
|
1149
|
-
parsedValue ? Number(parsedValue) : null
|
|
1150
|
-
);
|
|
1330
|
+
setStorageProfileEditingId(resolvedProfileId);
|
|
1151
1331
|
setIsStorageProfileSheetOpen(true);
|
|
1152
1332
|
}}
|
|
1153
|
-
disabled={!
|
|
1333
|
+
disabled={!resolvedProfileId}
|
|
1154
1334
|
aria-label="Editar perfil de email"
|
|
1155
1335
|
title="Editar perfil de email"
|
|
1156
1336
|
>
|
|
@@ -1184,7 +1364,8 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1184
1364
|
lockedTypeSlug="email"
|
|
1185
1365
|
onSaved={(profile: IntegrationProfileSheetSavedProfile) => {
|
|
1186
1366
|
setStorageProfileSelectedLabel(profile.name ?? '');
|
|
1187
|
-
|
|
1367
|
+
setResolvedProfileId(profile.id ?? null);
|
|
1368
|
+
handleChangeValue(String(profile.slug ?? ''), true);
|
|
1188
1369
|
}}
|
|
1189
1370
|
/>
|
|
1190
1371
|
</>
|
|
@@ -1225,11 +1406,11 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1225
1406
|
? t('selectMailProfile')
|
|
1226
1407
|
: t('selectWhatsAppProfile')
|
|
1227
1408
|
}
|
|
1228
|
-
value={parsedValue
|
|
1229
|
-
onChange={(
|
|
1230
|
-
handleChangeValue(
|
|
1409
|
+
value={parsedValue || null}
|
|
1410
|
+
onChange={(slug) =>
|
|
1411
|
+
handleChangeValue(slug != null ? String(slug) : '', true)
|
|
1231
1412
|
}
|
|
1232
|
-
valueType="
|
|
1413
|
+
valueType="string"
|
|
1233
1414
|
loadOptions={async ({ page, pageSize, search }) => {
|
|
1234
1415
|
const qs = new URLSearchParams({
|
|
1235
1416
|
page: String(page),
|
|
@@ -1249,7 +1430,7 @@ export const SettingField = ({ setting, className }: SettingFieldProps) => {
|
|
|
1249
1430
|
hasMore: (paged?.page ?? 0) < (paged?.lastPage ?? 0),
|
|
1250
1431
|
};
|
|
1251
1432
|
}}
|
|
1252
|
-
getOptionValue={(opt) => opt.
|
|
1433
|
+
getOptionValue={(opt) => opt.slug}
|
|
1253
1434
|
getOptionLabel={(opt) => String(opt.name ?? '')}
|
|
1254
1435
|
getOptionDescription={(opt) =>
|
|
1255
1436
|
String(opt.integration_provider?.slug ?? opt.slug ?? '')
|
|
@@ -158,6 +158,8 @@ const normalizeUserDashboardLayout = (item: WidgetLayout): LayoutItem => {
|
|
|
158
158
|
return layoutItem;
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
+
const DEFAULT_PAGE_SIZES = [6, 12, 24, 48, 96] as const;
|
|
162
|
+
|
|
161
163
|
export const DashboardContent = ({
|
|
162
164
|
dashboardSlug,
|
|
163
165
|
showHeader = true,
|
|
@@ -183,11 +185,41 @@ export const DashboardContent = ({
|
|
|
183
185
|
const [widgets, setWidgets] = useState<WidgetLayout[]>([]);
|
|
184
186
|
const [hasChanges, setHasChanges] = useState(false);
|
|
185
187
|
const [isSaving, setIsSaving] = useState(false);
|
|
188
|
+
const { data: generalSettings } = useQuery<{
|
|
189
|
+
data: Array<{ slug: string; value: string }>;
|
|
190
|
+
}>({
|
|
191
|
+
queryKey: ['setting-group-general'],
|
|
192
|
+
queryFn: async () => {
|
|
193
|
+
const response = await request<{
|
|
194
|
+
data: Array<{ slug: string; value: string }>;
|
|
195
|
+
}>({ url: '/setting/group/general', method: 'GET' });
|
|
196
|
+
return response.data;
|
|
197
|
+
},
|
|
198
|
+
staleTime: 5 * 60 * 1000,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const pageSizeOptions = useMemo(() => {
|
|
202
|
+
const setting = generalSettings?.data?.find(
|
|
203
|
+
(s) => s.slug === 'pagination-page-sizes'
|
|
204
|
+
);
|
|
205
|
+
if (!setting?.value) return DEFAULT_PAGE_SIZES;
|
|
206
|
+
try {
|
|
207
|
+
const parsed = JSON.parse(setting.value) as string[];
|
|
208
|
+
const sizes = parsed
|
|
209
|
+
.map(Number)
|
|
210
|
+
.filter((n) => !isNaN(n) && n > 0)
|
|
211
|
+
.sort((a, b) => a - b);
|
|
212
|
+
return sizes.length > 0 ? sizes : DEFAULT_PAGE_SIZES;
|
|
213
|
+
} catch {
|
|
214
|
+
return DEFAULT_PAGE_SIZES;
|
|
215
|
+
}
|
|
216
|
+
}, [generalSettings]);
|
|
217
|
+
|
|
186
218
|
const [componentsPage, setComponentsPage] = useState(1);
|
|
187
219
|
const [componentsPageSize, setComponentsPageSize] = usePersistedPageSize({
|
|
188
220
|
storageKey: 'pagination:global:pageSize',
|
|
189
221
|
defaultValue: 12,
|
|
190
|
-
allowedValues:
|
|
222
|
+
allowedValues: pageSizeOptions,
|
|
191
223
|
});
|
|
192
224
|
const [componentsSearchQuery, setComponentsSearchQuery] = useState('');
|
|
193
225
|
const [componentsModuleFilter, setComponentsModuleFilter] = useState('all');
|
|
@@ -134,6 +134,8 @@ type RequestError = {
|
|
|
134
134
|
};
|
|
135
135
|
};
|
|
136
136
|
|
|
137
|
+
const DEFAULT_PAGE_SIZES = [6, 12, 24, 48, 96] as const;
|
|
138
|
+
|
|
137
139
|
export function ComponentRolesTab() {
|
|
138
140
|
const t = useTranslations('core.DashboardManagement');
|
|
139
141
|
const { request, currentLocaleCode, getSettingValue } = useApp();
|
|
@@ -147,10 +149,40 @@ export function ComponentRolesTab() {
|
|
|
147
149
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
148
150
|
const [roleToDelete, setRoleToDelete] = useState<number | null>(null);
|
|
149
151
|
const [page, setPage] = useState(1);
|
|
152
|
+
const { data: generalSettings } = useQuery<{
|
|
153
|
+
data: Array<{ slug: string; value: string }>;
|
|
154
|
+
}>({
|
|
155
|
+
queryKey: ['setting-group-general'],
|
|
156
|
+
queryFn: async () => {
|
|
157
|
+
const response = await request<{
|
|
158
|
+
data: Array<{ slug: string; value: string }>;
|
|
159
|
+
}>({ url: '/setting/group/general', method: 'GET' });
|
|
160
|
+
return response.data;
|
|
161
|
+
},
|
|
162
|
+
staleTime: 5 * 60 * 1000,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const pageSizeOptions = useMemo(() => {
|
|
166
|
+
const setting = generalSettings?.data?.find(
|
|
167
|
+
(s) => s.slug === 'pagination-page-sizes'
|
|
168
|
+
);
|
|
169
|
+
if (!setting?.value) return DEFAULT_PAGE_SIZES;
|
|
170
|
+
try {
|
|
171
|
+
const parsed = JSON.parse(setting.value) as string[];
|
|
172
|
+
const sizes = parsed
|
|
173
|
+
.map(Number)
|
|
174
|
+
.filter((n) => !isNaN(n) && n > 0)
|
|
175
|
+
.sort((a, b) => a - b);
|
|
176
|
+
return sizes.length > 0 ? sizes : DEFAULT_PAGE_SIZES;
|
|
177
|
+
} catch {
|
|
178
|
+
return DEFAULT_PAGE_SIZES;
|
|
179
|
+
}
|
|
180
|
+
}, [generalSettings]);
|
|
181
|
+
|
|
150
182
|
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
151
183
|
storageKey: 'pagination:global:pageSize',
|
|
152
|
-
defaultValue:
|
|
153
|
-
allowedValues:
|
|
184
|
+
defaultValue: 12,
|
|
185
|
+
allowedValues: pageSizeOptions,
|
|
154
186
|
});
|
|
155
187
|
const searchQuery = '';
|
|
156
188
|
const debouncedSearch = useDebounce(searchQuery, 500);
|
|
@@ -540,7 +572,7 @@ export function ComponentRolesTab() {
|
|
|
540
572
|
<SelectValue />
|
|
541
573
|
</SelectTrigger>
|
|
542
574
|
<SelectContent>
|
|
543
|
-
{
|
|
575
|
+
{pageSizeOptions.map((size) => (
|
|
544
576
|
<SelectItem key={size} value={String(size)}>
|
|
545
577
|
{size}
|
|
546
578
|
</SelectItem>
|