bulkrax 9.3.4 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -1
  3. data/app/assets/javascripts/bulkrax/application.js +2 -1
  4. data/app/assets/javascripts/bulkrax/bulkrax.js +13 -4
  5. data/app/assets/javascripts/bulkrax/bulkrax_utils.js +96 -0
  6. data/app/assets/javascripts/bulkrax/datatables.js +1 -0
  7. data/app/assets/javascripts/bulkrax/entries.js +17 -10
  8. data/app/assets/javascripts/bulkrax/importers.js.erb +9 -2
  9. data/app/assets/javascripts/bulkrax/importers_stepper.js +2420 -0
  10. data/app/assets/stylesheets/bulkrax/application.css +1 -1
  11. data/app/assets/stylesheets/bulkrax/import_export.scss +9 -2
  12. data/app/assets/stylesheets/bulkrax/stepper/_header.scss +83 -0
  13. data/app/assets/stylesheets/bulkrax/stepper/_mixins.scss +26 -0
  14. data/app/assets/stylesheets/bulkrax/stepper/_navigation.scss +103 -0
  15. data/app/assets/stylesheets/bulkrax/stepper/_responsive.scss +46 -0
  16. data/app/assets/stylesheets/bulkrax/stepper/_review.scss +92 -0
  17. data/app/assets/stylesheets/bulkrax/stepper/_settings.scss +106 -0
  18. data/app/assets/stylesheets/bulkrax/stepper/_success.scss +26 -0
  19. data/app/assets/stylesheets/bulkrax/stepper/_summary.scss +171 -0
  20. data/app/assets/stylesheets/bulkrax/stepper/_upload.scss +339 -0
  21. data/app/assets/stylesheets/bulkrax/stepper/_validation.scss +237 -0
  22. data/app/assets/stylesheets/bulkrax/stepper/_variables.scss +46 -0
  23. data/app/assets/stylesheets/bulkrax/stepper.scss +32 -0
  24. data/app/controllers/bulkrax/guided_imports_controller.rb +175 -0
  25. data/app/controllers/bulkrax/importers_controller.rb +34 -28
  26. data/app/controllers/concerns/bulkrax/guided_import_demo_scenarios.rb +201 -0
  27. data/app/controllers/concerns/bulkrax/importer_file_handler.rb +217 -0
  28. data/app/factories/bulkrax/object_factory.rb +3 -2
  29. data/app/factories/bulkrax/valkyrie_object_factory.rb +61 -17
  30. data/app/jobs/bulkrax/export_work_job.rb +1 -3
  31. data/app/jobs/bulkrax/importer_job.rb +11 -4
  32. data/app/models/bulkrax/csv_entry.rb +27 -7
  33. data/app/models/bulkrax/entry.rb +4 -0
  34. data/app/models/bulkrax/importer.rb +31 -1
  35. data/app/models/concerns/bulkrax/has_matchers.rb +2 -2
  36. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +6 -5
  37. data/app/parsers/bulkrax/application_parser.rb +31 -5
  38. data/app/parsers/bulkrax/csv_parser.rb +42 -10
  39. data/app/parsers/concerns/bulkrax/csv_parser/csv_template_generation.rb +73 -0
  40. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation.rb +133 -0
  41. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_helpers.rb +282 -0
  42. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_hierarchy.rb +96 -0
  43. data/app/services/bulkrax/csv_template/column_builder.rb +60 -0
  44. data/app/services/bulkrax/csv_template/column_descriptor.rb +58 -0
  45. data/app/services/bulkrax/csv_template/csv_builder.rb +83 -0
  46. data/app/services/bulkrax/csv_template/explanation_builder.rb +57 -0
  47. data/app/services/bulkrax/csv_template/field_analyzer.rb +56 -0
  48. data/app/services/bulkrax/csv_template/file_path_generator.rb +47 -0
  49. data/app/services/bulkrax/csv_template/file_validator.rb +68 -0
  50. data/app/services/bulkrax/csv_template/mapping_manager.rb +55 -0
  51. data/app/services/bulkrax/csv_template/model_loader.rb +50 -0
  52. data/app/services/bulkrax/csv_template/row_builder.rb +35 -0
  53. data/app/services/bulkrax/csv_template/schema_analyzer.rb +70 -0
  54. data/app/services/bulkrax/csv_template/split_formatter.rb +44 -0
  55. data/app/services/bulkrax/csv_template/value_determiner.rb +68 -0
  56. data/app/services/bulkrax/stepper_response_formatter.rb +347 -0
  57. data/app/services/bulkrax/validation_error_csv_builder.rb +99 -0
  58. data/app/validators/bulkrax/csv_row/child_reference.rb +56 -0
  59. data/app/validators/bulkrax/csv_row/circular_reference.rb +71 -0
  60. data/app/validators/bulkrax/csv_row/controlled_vocabulary.rb +74 -0
  61. data/app/validators/bulkrax/csv_row/duplicate_identifier.rb +63 -0
  62. data/app/validators/bulkrax/csv_row/missing_source_identifier.rb +31 -0
  63. data/app/validators/bulkrax/csv_row/parent_reference.rb +59 -0
  64. data/app/validators/bulkrax/csv_row/required_values.rb +64 -0
  65. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +1 -1
  66. data/app/views/bulkrax/entries/_raw_metadata.html.erb +1 -1
  67. data/app/views/bulkrax/entries/show.html.erb +6 -6
  68. data/app/views/bulkrax/exporters/_form.html.erb +19 -43
  69. data/app/views/bulkrax/exporters/edit.html.erb +2 -2
  70. data/app/views/bulkrax/exporters/index.html.erb +5 -5
  71. data/app/views/bulkrax/exporters/new.html.erb +3 -5
  72. data/app/views/bulkrax/exporters/show.html.erb +3 -3
  73. data/app/views/bulkrax/guided_imports/new.html.erb +567 -0
  74. data/app/views/bulkrax/importers/_bagit_fields.html.erb +9 -9
  75. data/app/views/bulkrax/importers/_browse_everything.html.erb +1 -1
  76. data/app/views/bulkrax/importers/_csv_fields.html.erb +11 -11
  77. data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +23 -23
  78. data/app/views/bulkrax/importers/_edit_item_buttons.html.erb +2 -2
  79. data/app/views/bulkrax/importers/_file_uploader.html.erb +3 -3
  80. data/app/views/bulkrax/importers/_form.html.erb +4 -5
  81. data/app/views/bulkrax/importers/_oai_fields.html.erb +8 -18
  82. data/app/views/bulkrax/importers/_xml_fields.html.erb +13 -13
  83. data/app/views/bulkrax/importers/edit.html.erb +2 -2
  84. data/app/views/bulkrax/importers/index.html.erb +19 -14
  85. data/app/views/bulkrax/importers/new.html.erb +10 -9
  86. data/app/views/bulkrax/importers/show.html.erb +23 -7
  87. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +6 -6
  88. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +11 -11
  89. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +3 -3
  90. data/config/i18n-tasks.yml +195 -0
  91. data/config/locales/bulkrax.de.yml +504 -0
  92. data/config/locales/bulkrax.en.yml +487 -28
  93. data/config/locales/bulkrax.es.yml +504 -0
  94. data/config/locales/bulkrax.fr.yml +504 -0
  95. data/config/locales/bulkrax.it.yml +504 -0
  96. data/config/locales/bulkrax.pt-BR.yml +504 -0
  97. data/config/locales/bulkrax.zh.yml +503 -0
  98. data/config/routes.rb +10 -0
  99. data/lib/bulkrax/data/demo_scenarios.json +2235 -0
  100. data/lib/bulkrax/version.rb +1 -1
  101. data/lib/bulkrax.rb +31 -3
  102. data/lib/tasks/bulkrax_tasks.rake +0 -102
  103. metadata +55 -3
  104. /data/{app/services → lib}/wings/custom_queries/find_by_source_identifier.rb +0 -0
@@ -0,0 +1,339 @@
1
+ /* ====== Step Content ====== */
2
+ .step-content {
3
+ min-height: 400px;
4
+ }
5
+
6
+ .step-title {
7
+
8
+ h2,
9
+ .h2 {
10
+ font-size: 1.25rem;
11
+ font-weight: 600;
12
+ color: $color-text-dark;
13
+ margin-bottom: 5px;
14
+ }
15
+
16
+ .text-muted {
17
+ font-size: .875rem;
18
+ margin-bottom: 20px;
19
+ }
20
+
21
+ code {
22
+ color: $color-info-dark;
23
+ }
24
+ }
25
+
26
+ /* ====== Upload Mode Tabs ====== */
27
+ .upload-mode-tabs {
28
+ display: flex;
29
+ border: 1px solid $border-color;
30
+ border-radius: $border-radius;
31
+ background: none;
32
+ overflow: hidden;
33
+ }
34
+
35
+ .upload-mode-tab {
36
+ flex: 1;
37
+ padding: 12px 20px;
38
+ background: #fff;
39
+ border: none;
40
+ font-size: .875rem;
41
+ font-weight: 500;
42
+ color: $color-text-muted;
43
+ transition: color 0.3s ease, background-color 0.3s ease;
44
+
45
+ .fa {
46
+ margin-right: 6px;
47
+ }
48
+
49
+ &:hover {
50
+ color: $color-text-dark;
51
+ }
52
+
53
+ &+& {
54
+ border-left: 1px solid $border-color;
55
+ }
56
+
57
+ &.active {
58
+ color: $color-primary;
59
+ background: $bg-primary-light;
60
+ border-bottom: 2px solid $color-primary;
61
+ }
62
+ }
63
+
64
+ /* ====== Upload Files Zone ====== */
65
+ .upload-zone-wrapper {
66
+ margin: 25px 0;
67
+ }
68
+
69
+ .upload-dropzone {
70
+ @include dropzone-base(dashed, 60px, 40px);
71
+
72
+ &:hover .upload-icon {
73
+ background: $bg-primary-hover;
74
+ }
75
+
76
+ p {
77
+ margin: 5px 0;
78
+ }
79
+ }
80
+
81
+ .upload-dropzone-small {
82
+ @include dropzone-base(dashed, 20px, 20px);
83
+
84
+ &:hover .upload-icon-small {
85
+ background: $bg-primary-hover;
86
+ }
87
+
88
+ p {
89
+ margin: 5px 0;
90
+ }
91
+ }
92
+
93
+ .upload-icon {
94
+ width: 60px;
95
+ height: 60px;
96
+ margin: 0 auto 15px;
97
+ background: $bg-primary-light;
98
+ border-radius: 12px;
99
+ @include flex-center;
100
+ color: $color-primary;
101
+ font-size: 28px;
102
+ transition: background-color 0.3s ease;
103
+ }
104
+
105
+ .upload-accepted-types {
106
+ @include flex-center;
107
+ gap: 30px;
108
+ margin: 25px 0 0;
109
+
110
+ .fa {
111
+ font-size: 18px;
112
+ color: $color-text-muted;
113
+ margin: 0 6px;
114
+ }
115
+ }
116
+
117
+ .demo-scenarios {
118
+ margin-top: 15px;
119
+ padding: 15px;
120
+ background: $bg-primary-light;
121
+ border: 1px solid $border-info;
122
+ border-radius: 6px;
123
+
124
+ p {
125
+ margin-bottom: 10px;
126
+ }
127
+
128
+ .btn {
129
+ margin-bottom: 8px;
130
+ }
131
+ }
132
+
133
+ /* ====== Server Path Panel ====== */
134
+ .file-path-input-wrapper {
135
+ @include dropzone-base(solid, 60px, 40px);
136
+
137
+ .control-label {
138
+ font-size: 16px;
139
+ margin-bottom: 4px;
140
+ }
141
+
142
+ .text-muted {
143
+ margin-bottom: 12px;
144
+ }
145
+
146
+ .form-control {
147
+ font-size: 14px;
148
+ padding: 10px 12px;
149
+ margin: 25px 0 0;
150
+ }
151
+ }
152
+
153
+ /* ====== Uploaded Files ====== */
154
+ .uploaded-files-container {
155
+ border: 1px solid $border-color;
156
+ border-radius: $border-radius;
157
+ overflow: hidden;
158
+ margin: 25px 0;
159
+ }
160
+
161
+ .uploaded-files-list {
162
+ padding: 15px;
163
+ }
164
+
165
+ .file-row {
166
+ padding: 15px;
167
+ margin-bottom: 12px;
168
+ border: 1px solid $border-color;
169
+ border-radius: $border-radius;
170
+ background: $bg-light;
171
+
172
+ &:last-child {
173
+ margin-bottom: 0;
174
+ }
175
+ }
176
+
177
+ .file-row-main {
178
+ display: flex;
179
+ justify-content: space-between;
180
+ align-items: center;
181
+ }
182
+
183
+ .file-actions {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 8px;
187
+ }
188
+
189
+ .file-remove-btn {
190
+ border: 0;
191
+ color: $color-remove;
192
+ background: unset;
193
+ }
194
+
195
+ .file-info {
196
+ display: flex;
197
+ align-items: center;
198
+ gap: 15px;
199
+ }
200
+
201
+ .file-icon {
202
+ width: 45px;
203
+ height: 45px;
204
+ border-radius: $border-radius;
205
+ @include flex-center;
206
+ color: #fff;
207
+ font-size: 18px;
208
+ }
209
+
210
+ .file-icon-csv {
211
+ background: $color-primary;
212
+ }
213
+
214
+ .file-icon-zip {
215
+ background: $color-primary;
216
+ }
217
+
218
+ .file-details {
219
+ flex: 1;
220
+ }
221
+
222
+ .file-name {
223
+ font-size: 14px;
224
+ font-weight: 500;
225
+ color: $color-text-dark;
226
+ margin-bottom: 3px;
227
+ }
228
+
229
+ .file-subtitle {
230
+ font-size: 12px;
231
+ color: $color-text-muted;
232
+ }
233
+
234
+ .file-status {
235
+ font-size: .875rem;
236
+ }
237
+
238
+ .file-status-success {
239
+ color: $color-success;
240
+ }
241
+
242
+ .file-status-warning {
243
+ color: $color-warning;
244
+ }
245
+
246
+ .file-status-error {
247
+ color: $color-error;
248
+ }
249
+
250
+ /* Upload progress bar (chunked upload) - full-width like v1 */
251
+ .upload-progress-block {
252
+ margin-top: 10px;
253
+ padding-top: 8px;
254
+ border-top: 1px solid $border-color;
255
+ }
256
+
257
+ .upload-progress-label {
258
+ font-size: 12px;
259
+ color: $color-text-muted;
260
+ margin-bottom: 6px;
261
+ }
262
+
263
+ .upload-progress-bar-container {
264
+ height: 12px;
265
+ background: $border-color;
266
+ border-radius: 6px;
267
+ overflow: hidden;
268
+ width: 100%;
269
+ }
270
+
271
+ .upload-progress-bar {
272
+ height: 100%;
273
+ background: $color-primary;
274
+ border-radius: 6px;
275
+ transition: width 0.2s ease;
276
+ }
277
+
278
+ .upload-info-message {
279
+ padding: 0 15px 15px;
280
+ }
281
+
282
+ .upload-info {
283
+ display: flex;
284
+ align-items: center;
285
+ gap: 8px;
286
+ font-size: 13px;
287
+ color: $color-text-muted;
288
+ padding: 8px 0;
289
+
290
+ .fa {
291
+ color: $color-text-muted;
292
+ }
293
+ }
294
+
295
+ /* ====== File Upload Errors ====== */
296
+ .file-upload-errors {
297
+ margin: 20px 0;
298
+
299
+ .alert {
300
+ border-radius: 6px;
301
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
302
+
303
+ strong {
304
+ display: block;
305
+ margin-bottom: 8px;
306
+
307
+ .fa {
308
+ margin-right: 6px;
309
+ }
310
+ }
311
+
312
+ ul {
313
+ padding-left: 20px;
314
+ margin-bottom: 0;
315
+
316
+ li {
317
+ margin-bottom: 4px;
318
+ line-height: 1.6;
319
+
320
+ &:last-child {
321
+ margin-bottom: 0;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ /* ====== Download Template ====== */
329
+ .download-template-link {
330
+ display: flex;
331
+ align-items: center;
332
+ gap: 8px;
333
+ margin: 20px 0;
334
+ font-size: 14px;
335
+
336
+ .fa {
337
+ font-size: 15px;
338
+ }
339
+ }
@@ -0,0 +1,237 @@
1
+ /* ====== Validate Button ====== */
2
+ .validate-btn {
3
+ margin: 25px 0;
4
+ font-weight: 600;
5
+
6
+ .fa {
7
+ margin-right: 8px;
8
+ }
9
+ }
10
+
11
+ /* ====== Validation Results ====== */
12
+ .validation-results {
13
+ margin-top: 30px;
14
+ }
15
+
16
+ /* ====== Import Size Gauge ====== */
17
+ .import-size-gauge {
18
+ margin-bottom: 25px;
19
+ }
20
+
21
+ .gauge-card {
22
+ padding: 20px;
23
+ border-radius: $border-radius;
24
+ border: 1px solid;
25
+ }
26
+
27
+ // Gauge severity variants
28
+ $gauge-variants: (
29
+ optimal: (bg: $bg-success, border: $border-success, text: $color-success-dark, segment: $border-success, marker: $color-success-bright, radius: 6px 0 0 6px),
30
+ moderate: (bg: $bg-warning, border: $border-warning, text: $color-warning-dark, segment: $border-warning, marker: $color-warning, radius: 0),
31
+ large: (bg: $bg-error, border: $border-error, text: $color-error-dark, segment: $border-error, marker: $color-error, radius: 0 6px 6px 0),
32
+ );
33
+
34
+ @each $name, $colors in $gauge-variants {
35
+ .gauge-card-#{$name} {
36
+ background: map-get($colors, bg);
37
+ border-color: map-get($colors, border);
38
+ }
39
+
40
+ .gauge-segment-#{$name} {
41
+ background: map-get($colors, segment);
42
+
43
+ @if map-get($colors, radius) !=0 {
44
+ border-radius: map-get($colors, radius);
45
+ }
46
+ }
47
+
48
+ .gauge-marker-#{$name} {
49
+ background: map-get($colors, marker);
50
+ }
51
+ }
52
+
53
+ .gauge-header {
54
+ display: flex;
55
+ justify-content: space-between;
56
+ align-items: center;
57
+ margin-bottom: 12px;
58
+ font-size: 14px;
59
+ font-weight: 500;
60
+ }
61
+
62
+ .gauge-zone {
63
+ font-size: 12px;
64
+ font-weight: 600;
65
+ }
66
+
67
+ .gauge-track {
68
+ height: 12px;
69
+ border-radius: 6px;
70
+ overflow: visible;
71
+ display: flex;
72
+ position: relative;
73
+ margin-bottom: 8px;
74
+ }
75
+
76
+ .gauge-segment {
77
+ flex: 1;
78
+ }
79
+
80
+ .gauge-marker {
81
+ position: absolute;
82
+ top: 50%;
83
+ transform: translateY(-50%);
84
+ width: 20px;
85
+ height: 20px;
86
+ border-radius: 50%;
87
+ border: 3px solid #fff;
88
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
89
+ margin-left: -10px;
90
+ z-index: 10;
91
+ }
92
+
93
+ .gauge-labels {
94
+ display: flex;
95
+ justify-content: space-between;
96
+ font-size: 11px;
97
+ color: $color-text-muted;
98
+ margin-bottom: 10px;
99
+ }
100
+
101
+ .gauge-message {
102
+ margin: 0;
103
+ }
104
+
105
+ /* ====== Accordion ====== */
106
+ .accordion-wrapper {
107
+ margin-bottom: 25px;
108
+ }
109
+
110
+ .accordion-item {
111
+ border: 1px solid;
112
+ border-radius: $border-radius;
113
+ margin-bottom: 12px;
114
+ overflow: hidden;
115
+
116
+ &:last-child {
117
+ margin-bottom: 0;
118
+ }
119
+ }
120
+
121
+ // Accordion severity variants
122
+ $accordion-variants: (
123
+ success: (bg: $bg-success, border: $border-success, icon: $color-success-bright, count-bg: $border-success, count-text: $color-success-dark),
124
+ warning: (bg: $bg-warning, border: $border-warning, icon: $color-warning, count-bg: $border-warning, count-text: $color-warning-dark),
125
+ error: (bg: $bg-error, border: $border-error, icon: $color-error, count-bg: $border-error, count-text: $color-error-dark),
126
+ info: (bg: $bg-info, border: $border-info, icon: $color-info, count-bg: $border-info, count-text: $color-info-darker),
127
+ default: (bg: #fff, border: $border-color, icon: $color-text-muted, count-bg: $bg-muted, count-text: $color-text-default),
128
+ );
129
+
130
+ @each $name, $colors in $accordion-variants {
131
+ .accordion-#{$name} {
132
+ border-color: map-get($colors, border);
133
+ background: map-get($colors, bg);
134
+
135
+ .accordion-status-icon {
136
+ color: map-get($colors, icon);
137
+ }
138
+
139
+ .accordion-count {
140
+ background: map-get($colors, count-bg);
141
+ color: map-get($colors, count-text);
142
+ }
143
+
144
+ .accordion-content {
145
+ background: rgba(255, 255, 255, 0.8);
146
+ }
147
+ }
148
+ }
149
+
150
+ .accordion-header {
151
+ display: flex;
152
+ justify-content: space-between;
153
+ align-items: center;
154
+ padding: 12px 16px;
155
+ cursor: pointer;
156
+ transition: opacity 0.2s ease;
157
+ // Button reset — element changed from <div> to <button> for keyboard accessibility
158
+ width: 100%;
159
+ border: none;
160
+ background: none;
161
+ font: inherit;
162
+ color: inherit;
163
+ text-align: left;
164
+
165
+ &:hover {
166
+ opacity: 0.85;
167
+ }
168
+
169
+ &:focus-visible {
170
+ outline: 2px solid #4a90d9;
171
+ outline-offset: -2px;
172
+ border-radius: 4px;
173
+ }
174
+ }
175
+
176
+ .accordion-title-bar {
177
+ display: flex;
178
+ align-items: center;
179
+ gap: 8px;
180
+ font-size: 14px;
181
+ font-weight: 500;
182
+ }
183
+
184
+ .accordion-status-icon {
185
+ font-size: 16px;
186
+ }
187
+
188
+ .accordion-count {
189
+ font-size: 11px;
190
+ font-weight: 600;
191
+ padding: 2px 8px;
192
+ border-radius: 12px;
193
+ margin-left: 4px;
194
+ }
195
+
196
+ .accordion-chevron {
197
+ color: $color-text-muted;
198
+ font-size: 14px;
199
+ transition: transform 0.2s ease;
200
+ }
201
+
202
+ .accordion-content {
203
+ padding: 12px 16px;
204
+ border-top: 1px solid rgba(0, 0, 0, 0.08);
205
+ font-size: 13px;
206
+
207
+ ul {
208
+ margin: 5px 0;
209
+ padding-left: 0;
210
+ list-style: none;
211
+ }
212
+
213
+ li {
214
+ margin-bottom: 4px;
215
+ }
216
+ }
217
+
218
+ /* ====== Missing Required Fields ====== */
219
+ .missing-field-group {
220
+ margin-bottom: 16px;
221
+ background-color: $bg-error;
222
+ padding: 12px 16px;
223
+ border-radius: $border-radius;
224
+
225
+ &:last-child {
226
+ margin-bottom: 0;
227
+ }
228
+
229
+ ul {
230
+ margin: 4px 0 0 0;
231
+ padding-left: 20px;
232
+ }
233
+ }
234
+
235
+ .accordion-item.accordion-warning .missing-field-group {
236
+ background-color: $bg-warning;
237
+ }
@@ -0,0 +1,46 @@
1
+ // ---- Brand / Theme Colors ----
2
+ $color-primary: #2b6da5;
3
+ $color-success: #5cb85c;
4
+ $color-success-bright: #28a745;
5
+ $color-warning: #ffc107;
6
+ $color-error: #dc3545;
7
+ $color-info: #17a2b8;
8
+
9
+ // ---- Text Colors ----
10
+ $color-text-dark: #333;
11
+ $color-text-muted: #595f64;
12
+ $color-text-disabled: #6c757d;
13
+ $color-text-default: #495057;
14
+
15
+ // ---- Severity Dark Text ----
16
+ $color-success-dark: #155724;
17
+ $color-warning-dark: #856404;
18
+ $color-error-dark: #721c24;
19
+ $color-info-dark: #0c5460;
20
+ $color-info-darker: #004085;
21
+
22
+ // ---- Severity Backgrounds ----
23
+ $bg-success: #d7e5d7;
24
+ $bg-warning: #fff3cd;
25
+ $bg-error: #f8d7da;
26
+ $bg-info: #d1ecf1;
27
+
28
+ // ---- Severity Borders ----
29
+ $border-success: #c3e6cb;
30
+ $border-warning: #ffeaa7;
31
+ $border-error: #f5c6cb;
32
+ $border-info: #b8daff;
33
+ $border-info-light: #bee5eb;
34
+
35
+ // ---- Neutral Colors ----
36
+ $bg-light: #f8f9fa;
37
+ $border-color: #dee2e6;
38
+ $bg-muted: #e9ecef;
39
+ $bg-primary-light: #e7f3ff;
40
+ $bg-primary-hover: #d4e9ff;
41
+ $bg-success-light: #e8f5e9;
42
+ $bg-success-hover: #c8e6c9;
43
+ $color-remove: #d33a35;
44
+
45
+ // ---- Shared Dimensions ----
46
+ $border-radius: 8px;
@@ -0,0 +1,32 @@
1
+ /* Bulk Import Stepper Styles */
2
+
3
+ @import 'stepper/variables';
4
+ @import 'stepper/mixins';
5
+
6
+ .bulk-import-stepper-container {
7
+ max-width: 900px;
8
+ margin: 0 auto;
9
+ padding: 20px 0;
10
+
11
+ .text-muted {
12
+ color: $color-text-muted !important;
13
+ }
14
+ }
15
+
16
+ .stepper-wrapper {
17
+ background: #fff;
18
+ border-radius: $border-radius;
19
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
20
+ padding: 30px;
21
+ margin-bottom: 20px;
22
+ }
23
+
24
+ @import 'stepper/header';
25
+ @import 'stepper/success';
26
+ @import 'stepper/upload';
27
+ @import 'stepper/validation';
28
+ @import 'stepper/summary';
29
+ @import 'stepper/settings';
30
+ @import 'stepper/review';
31
+ @import 'stepper/navigation';
32
+ @import 'stepper/responsive';