@softdin/shared 0.1.3
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/README.md +48 -0
- package/package.json +50 -0
- package/src/a11y/announcer.ts +43 -0
- package/src/a11y/apply.ts +83 -0
- package/src/a11y/index.ts +31 -0
- package/src/a11y/state.ts +40 -0
- package/src/a11y/storage.ts +106 -0
- package/src/a11y/types.ts +187 -0
- package/src/api.ts +89 -0
- package/src/assets/softdin-logo.png +0 -0
- package/src/auth.ts +134 -0
- package/src/components/a11y/A11yLiveRegion.vue +11 -0
- package/src/components/a11y/AccessibilityMenuControls.vue +426 -0
- package/src/components/a11y/AccessibilityPreferencesPanel.vue +331 -0
- package/src/components/a11y/ColorSchemeQuickToggle.vue +105 -0
- package/src/components/a11y/SkipLink.vue +41 -0
- package/src/components/auth/AuthBrandHeader.vue +129 -0
- package/src/components/auth/AuthShell.vue +52 -0
- package/src/components/auth/DataProcessingConsentCheckbox.vue +303 -0
- package/src/components/auth/DataProcessingConsentForm.vue +111 -0
- package/src/components/forms/ErrorAlert.vue +170 -0
- package/src/components/forms/FormCancelButton.vue +87 -0
- package/src/components/forms/FormCloseButton.vue +114 -0
- package/src/components/forms/FormHelpButton.vue +109 -0
- package/src/components/forms/FormHelpModal.vue +193 -0
- package/src/components/forms/FormMaximizeButton.vue +143 -0
- package/src/components/forms/FormRefreshButton.vue +152 -0
- package/src/components/forms/FormSaveButton.vue +113 -0
- package/src/components/forms/PasswordInput.vue +154 -0
- package/src/components/navigation/CatalogListPagination.vue +113 -0
- package/src/config/apiBase.ts +37 -0
- package/src/lib/catalog-pagination.ts +27 -0
- package/src/lib/pagination.ts +86 -0
- package/src/lib/softdin-libreria.ts +50 -0
- package/src/style.css +278 -0
- package/src/types/auth.ts +146 -0
- package/src/types/softdin-libreria.d.ts +41 -0
- package/src/utils/apiError.ts +55 -0
- package/src/utils/connectivity.ts +33 -0
- package/src/utils/tenantLogo.ts +6 -0
package/src/style.css
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
--color-brand-50: #f0fdf4;
|
|
5
|
+
--color-brand-100: #dcfce7;
|
|
6
|
+
--color-brand-500: #22c55e;
|
|
7
|
+
--color-brand-600: #16a34a;
|
|
8
|
+
--color-brand-700: #15803d;
|
|
9
|
+
--color-brand-800: #166534;
|
|
10
|
+
--color-surface: #f8fafc;
|
|
11
|
+
--color-sidebar: #14532d;
|
|
12
|
+
--color-text: #0f172a;
|
|
13
|
+
--color-text-muted: #64748b;
|
|
14
|
+
--color-panel: #ffffff;
|
|
15
|
+
--color-border: #e2e8f0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:root {
|
|
19
|
+
--a11y-text-scale: 1;
|
|
20
|
+
--a11y-font-family: system-ui, 'Segoe UI', Roboto, sans-serif;
|
|
21
|
+
--a11y-line-height: 1.5;
|
|
22
|
+
--a11y-letter-spacing: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
html {
|
|
26
|
+
font-size: calc(16px * var(--a11y-text-scale));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
html,
|
|
30
|
+
body,
|
|
31
|
+
#app {
|
|
32
|
+
height: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
body {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-family: var(--a11y-font-family);
|
|
38
|
+
line-height: var(--a11y-line-height);
|
|
39
|
+
letter-spacing: var(--a11y-letter-spacing);
|
|
40
|
+
background: var(--color-surface);
|
|
41
|
+
color: var(--color-text);
|
|
42
|
+
-webkit-font-smoothing: antialiased;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.sr-only {
|
|
46
|
+
position: absolute;
|
|
47
|
+
width: 1px;
|
|
48
|
+
height: 1px;
|
|
49
|
+
padding: 0;
|
|
50
|
+
margin: -1px;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
clip: rect(0, 0, 0, 0);
|
|
53
|
+
white-space: nowrap;
|
|
54
|
+
border-width: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Controles interactivos: cursor que indica acción */
|
|
58
|
+
button:not(:disabled),
|
|
59
|
+
[type='button']:not(:disabled),
|
|
60
|
+
[type='submit']:not(:disabled),
|
|
61
|
+
[type='reset']:not(:disabled),
|
|
62
|
+
select:not(:disabled),
|
|
63
|
+
input[type='checkbox']:not(:disabled),
|
|
64
|
+
input[type='radio']:not(:disabled),
|
|
65
|
+
input[type='file']:not(:disabled),
|
|
66
|
+
input[type='color']:not(:disabled),
|
|
67
|
+
input[type='range']:not(:disabled),
|
|
68
|
+
label[for]:not([aria-disabled='true']),
|
|
69
|
+
label:has(input:not(:disabled)),
|
|
70
|
+
label:has(select:not(:disabled)),
|
|
71
|
+
a[href],
|
|
72
|
+
summary,
|
|
73
|
+
[role='button']:not([aria-disabled='true']):not(:disabled),
|
|
74
|
+
[role='tab']:not([aria-disabled='true']),
|
|
75
|
+
[role='switch']:not(:disabled),
|
|
76
|
+
[role='menuitem']:not([aria-disabled='true']),
|
|
77
|
+
[role='option']:not([aria-disabled='true']) {
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Controles deshabilitados o solo lectura */
|
|
82
|
+
button:disabled,
|
|
83
|
+
select:disabled,
|
|
84
|
+
input:disabled,
|
|
85
|
+
textarea:disabled,
|
|
86
|
+
[aria-disabled='true'],
|
|
87
|
+
.input-field-disabled,
|
|
88
|
+
.input-field:disabled,
|
|
89
|
+
.input-field[readonly][disabled] {
|
|
90
|
+
cursor: not-allowed;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* --- Tema oscuro --- */
|
|
94
|
+
html[data-a11y-theme='dark'] {
|
|
95
|
+
--color-brand-50: #052e16;
|
|
96
|
+
--color-brand-100: #14532d;
|
|
97
|
+
--color-brand-500: #4ade80;
|
|
98
|
+
--color-brand-600: #22c55e;
|
|
99
|
+
--color-brand-700: #16a34a;
|
|
100
|
+
--color-brand-800: #15803d;
|
|
101
|
+
--color-surface: #0b1220;
|
|
102
|
+
--color-sidebar: #052e16;
|
|
103
|
+
--color-text: #e2e8f0;
|
|
104
|
+
--color-text-muted: #94a3b8;
|
|
105
|
+
--color-panel: #111827;
|
|
106
|
+
--color-border: #334155;
|
|
107
|
+
color-scheme: dark;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
html[data-a11y-theme='dark'] body {
|
|
111
|
+
background: var(--color-surface);
|
|
112
|
+
color: var(--color-text);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
html[data-a11y-theme='dark'] .bg-white {
|
|
116
|
+
background-color: var(--color-panel) !important;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
html[data-a11y-theme='dark'] .bg-slate-50,
|
|
120
|
+
html[data-a11y-theme='dark'] .bg-gray-50 {
|
|
121
|
+
background-color: #0f172a !important;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
html[data-a11y-theme='dark'] .bg-slate-100,
|
|
125
|
+
html[data-a11y-theme='dark'] .bg-gray-100 {
|
|
126
|
+
background-color: #1e293b !important;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
html[data-a11y-theme='dark'] .bg-slate-200,
|
|
130
|
+
html[data-a11y-theme='dark'] .bg-gray-200 {
|
|
131
|
+
background-color: #334155 !important;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
html[data-a11y-theme='dark'] .text-slate-900,
|
|
135
|
+
html[data-a11y-theme='dark'] .text-gray-900,
|
|
136
|
+
html[data-a11y-theme='dark'] .text-black {
|
|
137
|
+
color: #f8fafc !important;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
html[data-a11y-theme='dark'] .text-slate-800,
|
|
141
|
+
html[data-a11y-theme='dark'] .text-gray-800 {
|
|
142
|
+
color: #e2e8f0 !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
html[data-a11y-theme='dark'] .text-slate-700,
|
|
146
|
+
html[data-a11y-theme='dark'] .text-gray-700 {
|
|
147
|
+
color: #cbd5e1 !important;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
html[data-a11y-theme='dark'] .text-slate-600,
|
|
151
|
+
html[data-a11y-theme='dark'] .text-gray-600 {
|
|
152
|
+
color: #94a3b8 !important;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
html[data-a11y-theme='dark'] .text-slate-500,
|
|
156
|
+
html[data-a11y-theme='dark'] .text-gray-500 {
|
|
157
|
+
color: #94a3b8 !important;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
html[data-a11y-theme='dark'] .text-slate-400,
|
|
161
|
+
html[data-a11y-theme='dark'] .text-gray-400 {
|
|
162
|
+
color: #64748b !important;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
html[data-a11y-theme='dark'] .border-slate-100,
|
|
166
|
+
html[data-a11y-theme='dark'] .border-gray-100,
|
|
167
|
+
html[data-a11y-theme='dark'] .border-slate-200,
|
|
168
|
+
html[data-a11y-theme='dark'] .border-gray-200,
|
|
169
|
+
html[data-a11y-theme='dark'] .divide-slate-100 > :not([hidden]) ~ :not([hidden]),
|
|
170
|
+
html[data-a11y-theme='dark'] .divide-slate-200 > :not([hidden]) ~ :not([hidden]) {
|
|
171
|
+
border-color: var(--color-border) !important;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
html[data-a11y-theme='dark'] .ring-slate-200,
|
|
175
|
+
html[data-a11y-theme='dark'] .ring-gray-200 {
|
|
176
|
+
--tw-ring-color: #334155 !important;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
html[data-a11y-theme='dark'] .shadow-sm,
|
|
180
|
+
html[data-a11y-theme='dark'] .shadow,
|
|
181
|
+
html[data-a11y-theme='dark'] .shadow-md {
|
|
182
|
+
--tw-shadow-color: rgb(0 0 0 / 0.45);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
html[data-a11y-theme='dark'] input:not([type='checkbox']):not([type='radio']),
|
|
186
|
+
html[data-a11y-theme='dark'] select,
|
|
187
|
+
html[data-a11y-theme='dark'] textarea {
|
|
188
|
+
background-color: #0f172a;
|
|
189
|
+
color: #e2e8f0;
|
|
190
|
+
border-color: #475569;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
html[data-a11y-theme='dark'] input:disabled,
|
|
194
|
+
html[data-a11y-theme='dark'] select:disabled,
|
|
195
|
+
html[data-a11y-theme='dark'] textarea:disabled {
|
|
196
|
+
background-color: #1e293b;
|
|
197
|
+
color: #64748b;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* --- Alto contraste --- */
|
|
201
|
+
html[data-a11y-contrast='high'] {
|
|
202
|
+
--color-surface: #ffffff;
|
|
203
|
+
--color-text: #000000;
|
|
204
|
+
--color-text-muted: #111111;
|
|
205
|
+
--color-panel: #ffffff;
|
|
206
|
+
--color-border: #000000;
|
|
207
|
+
--color-sidebar: #000000;
|
|
208
|
+
--color-brand-500: #006600;
|
|
209
|
+
--color-brand-600: #004d00;
|
|
210
|
+
--color-brand-700: #003300;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
html[data-a11y-theme='dark'][data-a11y-contrast='high'] {
|
|
214
|
+
--color-surface: #000000;
|
|
215
|
+
--color-text: #ffffff;
|
|
216
|
+
--color-text-muted: #ffffff;
|
|
217
|
+
--color-panel: #000000;
|
|
218
|
+
--color-border: #ffffff;
|
|
219
|
+
--color-sidebar: #000000;
|
|
220
|
+
--color-brand-500: #66ff66;
|
|
221
|
+
--color-brand-600: #33ff33;
|
|
222
|
+
--color-brand-700: #00cc00;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
html[data-a11y-contrast='high'] body {
|
|
226
|
+
background: var(--color-surface);
|
|
227
|
+
color: var(--color-text);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
html[data-a11y-contrast='high'] .bg-white,
|
|
231
|
+
html[data-a11y-contrast='high'] .bg-slate-50,
|
|
232
|
+
html[data-a11y-contrast='high'] .bg-slate-100 {
|
|
233
|
+
background-color: var(--color-panel) !important;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
html[data-a11y-contrast='high'] .text-slate-500,
|
|
237
|
+
html[data-a11y-contrast='high'] .text-slate-600,
|
|
238
|
+
html[data-a11y-contrast='high'] .text-gray-500,
|
|
239
|
+
html[data-a11y-contrast='high'] .text-gray-600 {
|
|
240
|
+
color: var(--color-text-muted) !important;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
html[data-a11y-contrast='high'] .border-slate-100,
|
|
244
|
+
html[data-a11y-contrast='high'] .border-slate-200,
|
|
245
|
+
html[data-a11y-contrast='high'] .ring-slate-200 {
|
|
246
|
+
border-color: var(--color-border) !important;
|
|
247
|
+
--tw-ring-color: var(--color-border) !important;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
html[data-a11y-contrast='high'] *:focus-visible {
|
|
251
|
+
outline: 3px solid #0000ff !important;
|
|
252
|
+
outline-offset: 2px !important;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
html[data-a11y-theme='dark'][data-a11y-contrast='high'] *:focus-visible {
|
|
256
|
+
outline-color: #ffff00 !important;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* --- Movimiento reducido --- */
|
|
260
|
+
@media (prefers-reduced-motion: reduce) {
|
|
261
|
+
html:not([data-a11y-motion='full']) *,
|
|
262
|
+
html:not([data-a11y-motion='full']) *::before,
|
|
263
|
+
html:not([data-a11y-motion='full']) *::after {
|
|
264
|
+
animation-duration: 0.01ms !important;
|
|
265
|
+
animation-iteration-count: 1 !important;
|
|
266
|
+
transition-duration: 0.01ms !important;
|
|
267
|
+
scroll-behavior: auto !important;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
html[data-a11y-motion='reduce'] *,
|
|
272
|
+
html[data-a11y-motion='reduce'] *::before,
|
|
273
|
+
html[data-a11y-motion='reduce'] *::after {
|
|
274
|
+
animation-duration: 0.01ms !important;
|
|
275
|
+
animation-iteration-count: 1 !important;
|
|
276
|
+
transition-duration: 0.01ms !important;
|
|
277
|
+
scroll-behavior: auto !important;
|
|
278
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export interface Tenant {
|
|
2
|
+
id: string
|
|
3
|
+
name: string
|
|
4
|
+
slug: string
|
|
5
|
+
database: string
|
|
6
|
+
status: string
|
|
7
|
+
has_logo?: boolean
|
|
8
|
+
role?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface User {
|
|
12
|
+
id: number
|
|
13
|
+
name: string
|
|
14
|
+
email: string
|
|
15
|
+
is_admin?: boolean
|
|
16
|
+
is_superuser?: boolean
|
|
17
|
+
is_platform_admin?: boolean
|
|
18
|
+
has_avatar?: boolean
|
|
19
|
+
requires_data_processing_consent?: boolean
|
|
20
|
+
data_processing_consent_accepted_at?: string | null
|
|
21
|
+
data_processing_consent_version?: string | null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PublicTenant {
|
|
25
|
+
id: string
|
|
26
|
+
name: string
|
|
27
|
+
slug: string
|
|
28
|
+
has_logo?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface RegisterPayload {
|
|
32
|
+
name: string
|
|
33
|
+
email: string
|
|
34
|
+
tenant_mode: 'new' | 'existing'
|
|
35
|
+
tenant_slug: string
|
|
36
|
+
tenant_name?: string
|
|
37
|
+
tenant_domain?: string
|
|
38
|
+
migrate?: boolean
|
|
39
|
+
seed?: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PublicTenantsResponse {
|
|
43
|
+
tenants: PublicTenant[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RegisterResponse {
|
|
47
|
+
message: string
|
|
48
|
+
user: User
|
|
49
|
+
mail_sent?: boolean
|
|
50
|
+
debug_activation_url?: string
|
|
51
|
+
debug_mail_error?: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ForgotPasswordResponse {
|
|
55
|
+
message: string
|
|
56
|
+
debug_reset_url?: string
|
|
57
|
+
debug_mail_error?: string
|
|
58
|
+
debug_mail_hint?: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface ResetPasswordPayload {
|
|
62
|
+
email: string
|
|
63
|
+
token: string
|
|
64
|
+
password: string
|
|
65
|
+
password_confirmation: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface MessageResponse {
|
|
69
|
+
message: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface CentralAdminLoginCredentials {
|
|
73
|
+
email: string
|
|
74
|
+
password: string
|
|
75
|
+
data_processing_consent_accepted?: boolean
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface LoginCredentials {
|
|
79
|
+
email: string
|
|
80
|
+
password: string
|
|
81
|
+
tenant: string
|
|
82
|
+
data_processing_consent_accepted?: boolean
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface UpdateProfilePayload {
|
|
86
|
+
name: string
|
|
87
|
+
password?: string
|
|
88
|
+
password_confirmation?: string
|
|
89
|
+
current_password?: string
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface ProfileUpdateResponse {
|
|
93
|
+
user: User
|
|
94
|
+
message: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ProfilePhotoResponse {
|
|
98
|
+
user: User
|
|
99
|
+
message: string
|
|
100
|
+
avatar_size?: number
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface CentralLoginResponse {
|
|
104
|
+
user: User
|
|
105
|
+
tenants: Tenant[]
|
|
106
|
+
tenant_selection_required?: boolean
|
|
107
|
+
central_access_available?: boolean
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface AuthResponse {
|
|
111
|
+
token: string
|
|
112
|
+
user: User
|
|
113
|
+
tenants: Tenant[]
|
|
114
|
+
active_tenant: Tenant | null
|
|
115
|
+
session_mode?: 'tenant' | 'central' | null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface MeResponse {
|
|
119
|
+
user: User
|
|
120
|
+
tenants: Tenant[]
|
|
121
|
+
active_tenant: Tenant | null
|
|
122
|
+
token_tenant?: Tenant | null
|
|
123
|
+
session_mode?: 'tenant' | 'central' | null
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface TenantLogoResponse {
|
|
127
|
+
tenant: Tenant
|
|
128
|
+
message: string
|
|
129
|
+
logo_size?: number
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface DataProcessingConsentPolicy {
|
|
133
|
+
version: string
|
|
134
|
+
title: string
|
|
135
|
+
summary: string
|
|
136
|
+
paragraphs: string[]
|
|
137
|
+
accepted?: boolean
|
|
138
|
+
accepted_at?: string | null
|
|
139
|
+
accepted_version?: string | null
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface DataProcessingConsentResponse {
|
|
143
|
+
message: string
|
|
144
|
+
accepted: boolean
|
|
145
|
+
user?: User
|
|
146
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
declare module 'softdinlibreriajs/src/EnumContinente.js' {
|
|
2
|
+
export interface EnumContinenteItem {
|
|
3
|
+
id: number
|
|
4
|
+
code: string
|
|
5
|
+
description: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default class EnumContinente {
|
|
9
|
+
static readonly ASIA: number
|
|
10
|
+
static readonly AFRICA: number
|
|
11
|
+
static readonly EUROPA: number
|
|
12
|
+
static readonly AMERICA_NORTE: number
|
|
13
|
+
static readonly AMERICA_SUR: number
|
|
14
|
+
static readonly OCEANIA: number
|
|
15
|
+
|
|
16
|
+
static getAll(): EnumContinenteItem[]
|
|
17
|
+
static getById(id: number): EnumContinenteItem | null
|
|
18
|
+
static getByDescription(description: string): EnumContinenteItem | null
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare module 'softdinlibreriajs/src/EnumTipoContrato.js' {
|
|
23
|
+
export interface EnumTipoContratoItem {
|
|
24
|
+
id: number
|
|
25
|
+
code: string
|
|
26
|
+
description: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default class EnumTipoContrato {
|
|
30
|
+
static readonly FIJO: number
|
|
31
|
+
static readonly INDEFINIDO: number
|
|
32
|
+
static readonly APRENDIZAJE: number
|
|
33
|
+
static readonly OBRA_LABOR: number
|
|
34
|
+
static readonly PRACTICAS_PASANTIAS: number
|
|
35
|
+
static readonly ASOCIACION: number
|
|
36
|
+
|
|
37
|
+
static getAll(): EnumTipoContratoItem[]
|
|
38
|
+
static getById(id: number): EnumTipoContratoItem | null
|
|
39
|
+
static getByDescription(description: string): EnumTipoContratoItem | null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { getConnectivityMessage } from './connectivity'
|
|
3
|
+
|
|
4
|
+
export * from './connectivity'
|
|
5
|
+
|
|
6
|
+
export function extractAxiosErrorMessage(error: unknown, fallback: string): string {
|
|
7
|
+
const connectivityMessage = getConnectivityMessage(error)
|
|
8
|
+
if (connectivityMessage) {
|
|
9
|
+
return connectivityMessage
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (!axios.isAxiosError(error) || !error.response) {
|
|
13
|
+
return fallback
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const status = error.response.status
|
|
17
|
+
const data = error.response.data
|
|
18
|
+
|
|
19
|
+
if (typeof data === 'object' && data !== null) {
|
|
20
|
+
const payload = data as { message?: string; errors?: Record<string, string[]> }
|
|
21
|
+
const firstFieldError = payload.errors
|
|
22
|
+
? Object.values(payload.errors).flat()[0]
|
|
23
|
+
: undefined
|
|
24
|
+
|
|
25
|
+
if (firstFieldError) {
|
|
26
|
+
return firstFieldError
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof payload.message === 'string' && payload.message.trim() !== '') {
|
|
30
|
+
return payload.message
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (status === 500) {
|
|
35
|
+
return 'Error interno del servidor. Revise storage/logs/laravel.log en softdin-api.'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (status === 503) {
|
|
39
|
+
return 'El servicio no está disponible en este momento.'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (status === 419) {
|
|
43
|
+
return 'La sesión expiró. Recargue la página e intente de nuevo.'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (typeof data === 'string' && data.trim() !== '') {
|
|
47
|
+
if (data.includes('<!DOCTYPE html>') || data.includes('<html')) {
|
|
48
|
+
return `${fallback} (HTTP ${status}: el servidor respondió HTML, no JSON).`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return fallback
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return `${fallback} (HTTP ${status}).`
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
|
|
3
|
+
let backendReachable = false
|
|
4
|
+
|
|
5
|
+
export function markBackendReachable(): void {
|
|
6
|
+
backendReachable = true
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function hasReachedBackend(): boolean {
|
|
10
|
+
return backendReachable
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isBrowserOffline(): boolean {
|
|
14
|
+
return typeof navigator !== 'undefined' && navigator.onLine === false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isConnectivityError(error: unknown): boolean {
|
|
18
|
+
if (axios.isAxiosError(error)) {
|
|
19
|
+
return !error.response
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return isBrowserOffline()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getConnectivityMessage(error: unknown): string | null {
|
|
26
|
+
if (!isConnectivityError(error)) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return hasReachedBackend()
|
|
31
|
+
? 'Se perdió la conexión con el servidor. Verifique su red e intente nuevamente.'
|
|
32
|
+
: 'No hay conexión con el servidor. Verifique su red e intente nuevamente.'
|
|
33
|
+
}
|