oxidized-web 0.14.0 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oxidized-web might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd7aba682137b4460c7f9f76ad8991416d3358c58a01c639b3c5457bac5ec2c0
4
- data.tar.gz: '091d541900d22a286cd735eb41d13d34efeb49be06a2f5fb69a196740fa08935'
3
+ metadata.gz: ef98fc626264e84687d7bdbfdb2a0a34aa5744086f34cdf3b84ddd823995246f
4
+ data.tar.gz: 7d43d90aa5027a130fba180db8c976200a19875978fb09bb9572d65a37ceb104
5
5
  SHA512:
6
- metadata.gz: 674f0040daf698447e7ad52f60a83cbceb60f1580b9abcca9328509f513c08728f0e906b8636d151e95c11c0d5294922b1bc2431c4be6ea438e66c47f64000e2
7
- data.tar.gz: 892d8416013ab3ff0ca4123725cae2e4ebdf78750cf9b10356a386a1ee952e18cdfcc2238c86bfd9626d40ff99436c8b195c31d28aaada97d686f59ba3adffec
6
+ metadata.gz: 9fdc33d367f0beb19545a31d73a830ecfb786d152cfdb8b6b28f0335c04b3fa40d524c47c49107cabe48785c788bcf38686e822038eb2e2cf37cf54b1b7267a8
7
+ data.tar.gz: 863d0e8381d5c55053922e581bf788fd93da4e45f90435e47b2afea678515f2d0e064b2471e81ce607b897c8deb6f0dbeb0fad57d67c088d4e323be2530f9bdd
@@ -19,7 +19,8 @@ jobs:
19
19
  runs-on: ubuntu-latest
20
20
  strategy:
21
21
  matrix:
22
- ruby-version: ['3.1', '3.2', '3.3']
22
+ ruby-version: ['3.1', '3.2', '3.3', '3.4', 'ruby-head']
23
+ continue-on-error: ${{ matrix.ruby-version == 'ruby-head' }}
23
24
 
24
25
  steps:
25
26
  - uses: actions/checkout@v4
@@ -30,13 +31,5 @@ jobs:
30
31
  with:
31
32
  ruby-version: ${{ matrix.ruby-version }}
32
33
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
33
- - name: rubocop
34
- uses: reviewdog/action-rubocop@v2
35
- with:
36
- rubocop_version: gemfile
37
- rubocop_extensions: rubocop-minitest:gemfile rubocop-rake:gemfile rubocop-rails:gemfile
38
- reporter: github-pr-review
39
34
  - name: Run tests
40
35
  run: bundle exec rake
41
- - uses: codecov/codecov-action@v4
42
- if: ${{ always() }}
@@ -13,6 +13,8 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/stale@v9
15
15
  with:
16
+ stale-issue-message: 'This issue is stale because it has been open 90 days with no activity.'
17
+ stale-pr-message: 'This PR is stale because it has been open 90 days with no activity.'
16
18
  operations-per-run: 500
17
- days-before-issue-stale: 90
18
- days-before-close: 30
19
+ days-before-stale: 90
20
+ days-before-close: -1
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  inherit_from: .rubocop_todo.yml
2
- require:
2
+ plugins:
3
3
  - rubocop-rails
4
4
  - rubocop-rake
5
5
  - rubocop-minitest
data/.rubocop_todo.yml CHANGED
@@ -1,32 +1,27 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-06-28 07:42:20 UTC using RuboCop version 1.64.1.
3
+ # on 2025-02-20 10:05:16 UTC using RuboCop version 1.72.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 5
9
+ # Offense count: 2
10
10
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
11
11
  Metrics/AbcSize:
12
- Max: 52
12
+ Max: 31
13
13
 
14
14
  # Offense count: 1
15
- # Configuration parameters: CountBlocks.
16
- Metrics/BlockNesting:
17
- Max: 4
18
-
19
- # Offense count: 2
20
15
  # Configuration parameters: AllowedMethods, AllowedPatterns.
21
16
  Metrics/CyclomaticComplexity:
22
17
  Max: 9
23
18
 
24
- # Offense count: 9
19
+ # Offense count: 5
25
20
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
26
21
  Metrics/MethodLength:
27
- Max: 33
22
+ Max: 28
28
23
 
29
- # Offense count: 2
24
+ # Offense count: 1
30
25
  # Configuration parameters: AllowedMethods, AllowedPatterns.
31
26
  Metrics/PerceivedComplexity:
32
27
  Max: 11
data/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ ## [0.15.1 – 2025-02-20]
7
+ This minor release fixes javascript errors.
8
+
9
+ ### Fixed
10
+ - Fix javascript not working (@robertcheramy)
11
+
12
+ ## [0.15.0 – 2025-02-17]
13
+ This release fixes a security issue on the RANCID migration page.
14
+ A non-authenticated user could gain control over the Linux user running
15
+ oxidized-web. The RANCID migration page was already deprecated in version
16
+ 0.14.0, so it has been completely removed in this new version.
17
+ Thank you to Jon O'Reilly and Jamie Riden from NetSPI for discovering and
18
+ reporting this security issue!
19
+
20
+ ### Changed
21
+ - Update datatables.net to 2.2.2 and datatables.net-buttons to 3.2.2 (@robertcheramy)
22
+ - remove the RANCID migration page (@robertchreamy)
23
+ - dependency on oxidized 0.31 (@robertchreamy)
24
+ - Update datatables.net to 2.2.1 and datatables.net-buttons to 3.2.1 (@robertcheramy)
25
+
26
+ ### Fixed
27
+ - #302: group name containing a '/' produced a Sinatra error (@robertcheramy)
28
+
6
29
 
7
30
  ## [0.14.0 - 2024-06-28]
8
31
 
data/Rakefile CHANGED
@@ -26,6 +26,7 @@ task :test do
26
26
  Rake::TestTask.new do |t|
27
27
  t.libs << 'spec'
28
28
  t.test_files = FileList['spec/**/*_spec.rb']
29
+ t.ruby_opts = ['-W:deprecated']
29
30
  t.warning = true
30
31
  t.verbose = true
31
32
  end
data/docs/development.md CHANGED
@@ -23,7 +23,9 @@ scripts, you have to stop an restart `bundle exec oxidized`.
23
23
 
24
24
  ## Paralell development between oxidized and oxidized-web
25
25
  You may need to make some changes in oxidized **and** oxidized-web. For this,
26
- git clone oxidized and oxidized-web in a common root directory, add the direct
26
+ git clone oxidized and oxidized-web in a common root directory.
27
+
28
+ Then you can link your oxidized-web with the oxidized, add the direct
27
29
  dependency to ../oxidized-web in oxidized and run oxidized from the oxidized
28
30
  repo:
29
31
 
@@ -45,6 +47,19 @@ If your changes to oxidized **AND** oxidzed-web are dependent from another, make
45
47
  sure you document this in the respectives CHANGELOG.md, so that everyone is
46
48
  informed at the next release.
47
49
 
50
+ Note: you can also add the dependency to oxidized in oxidized-web, in the same
51
+ fashion:
52
+ ```shell
53
+ git clone git@github.com:ytti/oxidized-web.git
54
+ git clone git@github.com:ytti/oxidized.git
55
+ cd oxidized-web
56
+ bundle config set --local path 'vendor/bundle'
57
+ echo "gem 'oxidized', path: '../oxidized'" >> Gemfile
58
+ bundle install
59
+ bundle exec oxidized
60
+ ```
61
+
62
+
48
63
  # Update the weblibs
49
64
  The weblibs are beeing downloaded and maintained by `npm`.
50
65
 
@@ -113,6 +128,9 @@ Run Oxidized-web from git against the latest git of Oxidized (see above).
113
128
 
114
129
  Do not integrate late PRs into master if they do not fix issues for the release. The must wait for the next release.
115
130
 
131
+ When testing the web application, open the javascript console in the browser to
132
+ see any errors.
133
+
116
134
  ## Version numbering
117
135
  Oxidized-web versions are nummered like 0.major.minor
118
136
  - major is incremented when releasing new features. minor is then set to 0
@@ -148,9 +166,6 @@ Push the gem with ‘rake push’
148
166
 
149
167
  You need an account at rubygems which is allowed to push oxidized
150
168
 
151
- ## Release in docker.io
152
- The OCI-Containter is automatically build and pushed to docker.io by github
153
-
154
169
  ## Update CHANGELOG.md for next release
155
170
  Add
156
171
  ```
@@ -1,30 +1,3 @@
1
- // Add a line for a new file to upload
2
- var add_file_upload = function() {
3
- var rancidDbDiv = $("div[id^='rancidDb']:last");
4
- var num = parseInt(rancidDbDiv.prop("id").match(/\d+/g)) + 1;
5
- rancidDbDiv.clone(true)
6
- .prop("id", "rancidDb" + num)
7
- .insertAfter(rancidDbDiv);
8
- $("input[id^='file']:last")
9
- .prop("id", "file" + num)
10
- .prop("name", "file" + num)
11
- .parents('.input-group')
12
- .find(':text')
13
- .val('');
14
- $("input[id^='group']:last")
15
- .prop("id", "group" + num)
16
- .prop("name", "group" + num);
17
- };
18
-
19
- var onFileSelected = function() {
20
- $(document).on('change', '.btn-file :file', function() {
21
- var input = $(this),
22
- numFiles = input.get(0).files ? input.get(0).files.length : 1,
23
- label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
24
- input.trigger('fileSelect', [numFiles, label]);
25
- });
26
- };
27
-
28
1
  var convertTime = function() {
29
2
  /* Convert UTC times to local browser times
30
3
  * Requires that the times on the server are UTC
@@ -49,17 +22,7 @@ var convertTime = function() {
49
22
  };
50
23
 
51
24
  $(function() {
52
- onFileSelected();
53
25
  convertTime();
54
- // Add a row to the migration form
55
- $("#add").click(function() {
56
- add_file_upload();
57
- });
58
-
59
- // Updates textbox with filename on fileSelect event
60
- $('.btn-file :file').on('fileSelect', function(e, numFiles, label) {
61
- $(this).parents('.input-group').find(':text').val(label);
62
- });
63
26
 
64
27
  // Reloads the nodes from a source by calling the /reload.json URI
65
28
  $('#reload').click(function() {
@@ -171,22 +171,52 @@ div.dt-button-collection span.dt-button-spacer.bar {
171
171
  box-shadow: none !important;
172
172
  }
173
173
  }
174
- html.dark div.dt-button-info {
175
- background-color: var(--dt-html-background);
176
- border: 1px solid rgba(255, 255, 255, 0.15);
177
- }
178
-
179
174
  div.dt-buttons div.btn-group {
180
175
  position: initial;
181
176
  }
182
- div.dt-buttons div.dropdown-menu {
177
+ div.dt-buttons span.dt-button-spacer.empty {
178
+ margin: 1px;
179
+ }
180
+ div.dt-buttons span.dt-button-spacer.bar:empty {
181
+ height: inherit;
182
+ }
183
+ div.dt-buttons .btn.processing {
184
+ color: rgba(0, 0, 0, 0.2);
185
+ }
186
+ div.dt-buttons .btn.processing:after {
187
+ position: absolute;
188
+ top: 50%;
189
+ left: 50%;
190
+ width: 16px;
191
+ height: 16px;
192
+ margin: -8px 0 0 -8px;
193
+ box-sizing: border-box;
194
+ display: block;
195
+ content: " ";
196
+ border: 2px solid rgb(40, 40, 40);
197
+ border-radius: 50%;
198
+ border-left-color: transparent;
199
+ border-right-color: transparent;
200
+ animation: dtb-spinner 1500ms infinite linear;
201
+ -o-animation: dtb-spinner 1500ms infinite linear;
202
+ -ms-animation: dtb-spinner 1500ms infinite linear;
203
+ -webkit-animation: dtb-spinner 1500ms infinite linear;
204
+ -moz-animation: dtb-spinner 1500ms infinite linear;
205
+ }
206
+
207
+ div.dropdown-menu.dt-button-collection {
183
208
  margin-top: 4px;
184
209
  width: 200px;
185
210
  }
186
- div.dt-buttons div.dropdown-menu .dt-button {
211
+ div.dropdown-menu.dt-button-collection .dt-button {
187
212
  position: relative;
188
213
  }
189
- div.dt-buttons div.dropdown-menu div.dt-button-split {
214
+ div.dropdown-menu.dt-button-collection .dt-button.dropdown-toggle::after {
215
+ position: absolute;
216
+ right: 12px;
217
+ top: 14px;
218
+ }
219
+ div.dropdown-menu.dt-button-collection div.dt-button-split {
190
220
  display: flex;
191
221
  flex-direction: row;
192
222
  flex-wrap: wrap;
@@ -194,12 +224,12 @@ div.dt-buttons div.dropdown-menu div.dt-button-split {
194
224
  align-content: flex-start;
195
225
  align-items: stretch;
196
226
  }
197
- div.dt-buttons div.dropdown-menu div.dt-button-split a:first-child {
227
+ div.dropdown-menu.dt-button-collection div.dt-button-split a:first-child {
198
228
  min-width: auto;
199
229
  flex: 1 0 50px;
200
230
  padding-right: 0;
201
231
  }
202
- div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child {
232
+ div.dropdown-menu.dt-button-collection div.dt-button-split button:last-child {
203
233
  min-width: 33px;
204
234
  flex: 0;
205
235
  background: transparent;
@@ -209,15 +239,11 @@ div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child {
209
239
  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);
210
240
  overflow: visible;
211
241
  }
212
- div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child:hover {
242
+ div.dropdown-menu.dt-button-collection div.dt-button-split button:last-child:hover {
213
243
  color: var(--bs-dropdown-link-hover-color);
214
244
  background-color: var(--bs-dropdown-link-hover-bg);
215
245
  }
216
- div.dt-buttons div.dropdown-menu div.dt-button-split button:last-child:after {
217
- position: relative;
218
- left: -3px;
219
- }
220
- div.dt-buttons div.dropdown-menu.fixed {
246
+ div.dropdown-menu.dt-button-collection.fixed {
221
247
  position: fixed;
222
248
  display: block;
223
249
  top: 50%;
@@ -227,77 +253,73 @@ div.dt-buttons div.dropdown-menu.fixed {
227
253
  background-color: white;
228
254
  padding: 0.5em;
229
255
  }
230
- div.dt-buttons div.dropdown-menu.fixed.two-column {
256
+ div.dropdown-menu.dt-button-collection.fixed.two-column {
231
257
  margin-left: -200px;
232
258
  }
233
- div.dt-buttons div.dropdown-menu.fixed.three-column {
259
+ div.dropdown-menu.dt-button-collection.fixed.three-column {
234
260
  margin-left: -225px;
235
261
  }
236
- div.dt-buttons div.dropdown-menu.fixed.four-column {
262
+ div.dropdown-menu.dt-button-collection.fixed.four-column {
237
263
  margin-left: -300px;
238
264
  }
239
- div.dt-buttons div.dropdown-menu.fixed.columns {
265
+ div.dropdown-menu.dt-button-collection.fixed.columns {
240
266
  margin-left: -409px;
241
267
  }
242
268
  @media screen and (max-width: 1024px) {
243
- div.dt-buttons div.dropdown-menu.fixed.columns {
269
+ div.dropdown-menu.dt-button-collection.fixed.columns {
244
270
  margin-left: -308px;
245
271
  }
246
272
  }
247
273
  @media screen and (max-width: 640px) {
248
- div.dt-buttons div.dropdown-menu.fixed.columns {
274
+ div.dropdown-menu.dt-button-collection.fixed.columns {
249
275
  margin-left: -203px;
250
276
  }
251
277
  }
252
278
  @media screen and (max-width: 460px) {
253
- div.dt-buttons div.dropdown-menu.fixed.columns {
279
+ div.dropdown-menu.dt-button-collection.fixed.columns {
254
280
  margin-left: -100px;
255
281
  }
256
282
  }
257
- div.dt-buttons div.dropdown-menu.fixed > :last-child {
283
+ div.dropdown-menu.dt-button-collection.fixed > :last-child {
258
284
  max-height: 100vh;
259
285
  overflow: auto;
260
286
  }
261
- div.dt-buttons div.dropdown-menu.two-column > :last-child, div.dt-buttons div.dropdown-menu.three-column > :last-child, div.dt-buttons div.dropdown-menu.four-column > :last-child {
287
+ div.dropdown-menu.dt-button-collection.two-column > :last-child, div.dropdown-menu.dt-button-collection.three-column > :last-child, div.dropdown-menu.dt-button-collection.four-column > :last-child {
262
288
  display: block !important;
263
- -webkit-column-gap: 8px;
264
- -moz-column-gap: 8px;
265
- -ms-column-gap: 8px;
266
- -o-column-gap: 8px;
267
289
  column-gap: 8px;
268
290
  }
269
- div.dt-buttons div.dropdown-menu.two-column > :last-child > *, div.dt-buttons div.dropdown-menu.three-column > :last-child > *, div.dt-buttons div.dropdown-menu.four-column > :last-child > * {
291
+ div.dropdown-menu.dt-button-collection.two-column > :last-child > *, div.dropdown-menu.dt-button-collection.three-column > :last-child > *, div.dropdown-menu.dt-button-collection.four-column > :last-child > * {
270
292
  -webkit-column-break-inside: avoid;
271
293
  break-inside: avoid;
272
294
  }
273
- div.dt-buttons div.dropdown-menu.two-column {
295
+ div.dropdown-menu.dt-button-collection.two-column {
274
296
  width: 400px;
275
297
  }
276
- div.dt-buttons div.dropdown-menu.two-column > :last-child {
298
+ div.dropdown-menu.dt-button-collection.two-column > :last-child {
277
299
  padding-bottom: 1px;
278
300
  column-count: 2;
279
301
  }
280
- div.dt-buttons div.dropdown-menu.three-column {
302
+ div.dropdown-menu.dt-button-collection.three-column {
281
303
  width: 450px;
282
304
  }
283
- div.dt-buttons div.dropdown-menu.three-column > :last-child {
305
+ div.dropdown-menu.dt-button-collection.three-column > :last-child {
284
306
  padding-bottom: 1px;
285
307
  column-count: 3;
286
308
  }
287
- div.dt-buttons div.dropdown-menu.four-column {
309
+ div.dropdown-menu.dt-button-collection.four-column {
288
310
  width: 600px;
289
311
  }
290
- div.dt-buttons div.dropdown-menu.four-column > :last-child {
312
+ div.dropdown-menu.dt-button-collection.four-column > :last-child {
291
313
  padding-bottom: 1px;
292
314
  column-count: 4;
293
315
  }
294
- div.dt-buttons div.dropdown-menu .dt-button {
316
+ div.dropdown-menu.dt-button-collection .dt-button {
295
317
  border-radius: 0;
296
318
  }
297
- div.dt-buttons div.dropdown-menu.columns {
319
+ div.dropdown-menu.dt-button-collection.columns {
298
320
  width: auto;
299
321
  }
300
- div.dt-buttons div.dropdown-menu.columns > :last-child {
322
+ div.dropdown-menu.dt-button-collection.columns > :last-child {
301
323
  display: flex;
302
324
  flex-wrap: wrap;
303
325
  justify-content: flex-start;
@@ -306,70 +328,41 @@ div.dt-buttons div.dropdown-menu.columns > :last-child {
306
328
  width: 818px;
307
329
  padding-bottom: 1px;
308
330
  }
309
- div.dt-buttons div.dropdown-menu.columns > :last-child .dt-button {
331
+ div.dropdown-menu.dt-button-collection.columns > :last-child .dt-button {
310
332
  min-width: 200px;
311
333
  flex: 0 1;
312
334
  margin: 0;
313
335
  }
314
- div.dt-buttons div.dropdown-menu.columns.dtb-b3 > :last-child, div.dt-buttons div.dropdown-menu.columns.dtb-b2 > :last-child, div.dt-buttons div.dropdown-menu.columns.dtb-b1 > :last-child {
336
+ div.dropdown-menu.dt-button-collection.columns.dtb-b3 > :last-child, div.dropdown-menu.dt-button-collection.columns.dtb-b2 > :last-child, div.dropdown-menu.dt-button-collection.columns.dtb-b1 > :last-child {
315
337
  justify-content: space-between;
316
338
  }
317
- div.dt-buttons div.dropdown-menu.columns.dtb-b3 .dt-button {
339
+ div.dropdown-menu.dt-button-collection.columns.dtb-b3 .dt-button {
318
340
  flex: 1 1 32%;
319
341
  }
320
- div.dt-buttons div.dropdown-menu.columns.dtb-b2 .dt-button {
342
+ div.dropdown-menu.dt-button-collection.columns.dtb-b2 .dt-button {
321
343
  flex: 1 1 48%;
322
344
  }
323
- div.dt-buttons div.dropdown-menu.columns.dtb-b1 .dt-button {
345
+ div.dropdown-menu.dt-button-collection.columns.dtb-b1 .dt-button {
324
346
  flex: 1 1 100%;
325
347
  }
326
348
  @media screen and (max-width: 1024px) {
327
- div.dt-buttons div.dropdown-menu.columns > :last-child {
349
+ div.dropdown-menu.dt-button-collection.columns > :last-child {
328
350
  width: 612px;
329
351
  }
330
352
  }
331
353
  @media screen and (max-width: 640px) {
332
- div.dt-buttons div.dropdown-menu.columns > :last-child {
354
+ div.dropdown-menu.dt-button-collection.columns > :last-child {
333
355
  width: 406px;
334
356
  }
335
- div.dt-buttons div.dropdown-menu.columns.dtb-b3 .dt-button {
357
+ div.dropdown-menu.dt-button-collection.columns.dtb-b3 .dt-button {
336
358
  flex: 0 1 32%;
337
359
  }
338
360
  }
339
361
  @media screen and (max-width: 460px) {
340
- div.dt-buttons div.dropdown-menu.columns > :last-child {
362
+ div.dropdown-menu.dt-button-collection.columns > :last-child {
341
363
  width: 200px;
342
364
  }
343
365
  }
344
- div.dt-buttons span.dt-button-spacer.empty {
345
- margin: 1px;
346
- }
347
- div.dt-buttons span.dt-button-spacer.bar:empty {
348
- height: inherit;
349
- }
350
- div.dt-buttons .btn.processing {
351
- color: rgba(0, 0, 0, 0.2);
352
- }
353
- div.dt-buttons .btn.processing:after {
354
- position: absolute;
355
- top: 50%;
356
- left: 50%;
357
- width: 16px;
358
- height: 16px;
359
- margin: -8px 0 0 -8px;
360
- box-sizing: border-box;
361
- display: block;
362
- content: " ";
363
- border: 2px solid rgb(40, 40, 40);
364
- border-radius: 50%;
365
- border-left-color: transparent;
366
- border-right-color: transparent;
367
- animation: dtb-spinner 1500ms infinite linear;
368
- -o-animation: dtb-spinner 1500ms infinite linear;
369
- -ms-animation: dtb-spinner 1500ms infinite linear;
370
- -webkit-animation: dtb-spinner 1500ms infinite linear;
371
- -moz-animation: dtb-spinner 1500ms infinite linear;
372
- }
373
366
 
374
367
  div.dt-button-background {
375
368
  position: fixed;
@@ -391,8 +384,12 @@ div.dt-button-background {
391
384
  float: none;
392
385
  }
393
386
  }
387
+ div.dt-button-info {
388
+ background-color: var(--bs-body-bg);
389
+ border: 1px solid var(--bs-border-color-translucent);
390
+ }
391
+
394
392
  :root[data-bs-theme=dark] div.dropdown-menu.dt-button-collection.fixed {
395
- background-color: rgb(33, 37, 41);
396
- border: 1px solid rgba(255, 255, 255, 0.15);
397
- border-radius: 8px;
393
+ background-color: var(--bs-body-bg);
394
+ border: 1px solid var(--bs-border-color-translucent);
398
395
  }
@@ -60,12 +60,11 @@ $.extend(true, DataTable.Buttons.defaults, {
60
60
  },
61
61
  button: {
62
62
  className: 'btn btn-secondary',
63
- active: 'active'
63
+ active: 'active',
64
+ dropHtml: '',
65
+ dropClass: 'dropdown-toggle'
64
66
  },
65
67
  collection: {
66
- action: {
67
- dropHtml: ''
68
- },
69
68
  container: {
70
69
  tag: 'div',
71
70
  className: 'dropdown-menu dt-button-collection'
@@ -90,9 +89,8 @@ $.extend(true, DataTable.Buttons.defaults, {
90
89
  },
91
90
  dropdown: {
92
91
  tag: 'button',
93
- dropHtml: '',
94
92
  className:
95
- 'btn btn-secondary dt-button-split-drop dropdown-toggle dropdown-toggle-split',
93
+ 'btn btn-secondary dt-button-split-drop dropdown-toggle-split',
96
94
  closeButton: false,
97
95
  align: 'split-left',
98
96
  splitAlignClass: 'dt-button-split-left'
@@ -109,7 +107,6 @@ $.extend(true, DataTable.Buttons.defaults, {
109
107
  }
110
108
  });
111
109
 
112
- DataTable.ext.buttons.collection.className += ' dropdown-toggle';
113
110
  DataTable.ext.buttons.collection.rightAlignClassName = 'dropdown-menu-right';
114
111
 
115
112
 
@@ -1,4 +1,3 @@
1
- @charset "UTF-8";
2
1
  :root {
3
2
  --dt-row-selected: 13, 110, 253;
4
3
  --dt-row-selected-text: 255, 255, 255;
@@ -31,17 +30,26 @@ table.dataTable tr.dt-hasChild td.dt-control:before {
31
30
  border-bottom: 0px solid transparent;
32
31
  border-right: 5px solid transparent;
33
32
  }
33
+ table.dataTable tfoot:empty {
34
+ display: none;
35
+ }
34
36
 
35
37
  html.dark table.dataTable td.dt-control:before,
36
- :root[data-bs-theme=dark] table.dataTable td.dt-control:before {
38
+ :root[data-bs-theme=dark] table.dataTable td.dt-control:before,
39
+ :root[data-theme=dark] table.dataTable td.dt-control:before {
37
40
  border-left-color: rgba(255, 255, 255, 0.5);
38
41
  }
39
42
  html.dark table.dataTable tr.dt-hasChild td.dt-control:before,
40
- :root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before {
43
+ :root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before,
44
+ :root[data-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before {
41
45
  border-top-color: rgba(255, 255, 255, 0.5);
42
46
  border-left-color: transparent;
43
47
  }
44
48
 
49
+ div.dt-scroll {
50
+ width: 100%;
51
+ }
52
+
45
53
  div.dt-scroll-body thead tr,
46
54
  div.dt-scroll-body tfoot tr {
47
55
  height: 0;
@@ -72,8 +80,8 @@ table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before {
72
80
  position: absolute;
73
81
  display: block;
74
82
  bottom: 50%;
75
- content: "";
76
- content: ""/"";
83
+ content: "\25B2";
84
+ content: "\25B2"/"";
77
85
  }
78
86
  table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after,
79
87
  table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after,
@@ -81,8 +89,8 @@ table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after {
81
89
  position: absolute;
82
90
  display: block;
83
91
  top: 50%;
84
- content: "";
85
- content: ""/"";
92
+ content: "\25BC";
93
+ content: "\25BC"/"";
86
94
  }
87
95
  table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc,
88
96
  table.dataTable thead > tr > td.dt-orderable-asc,
@@ -233,6 +241,11 @@ table.dataTable th,
233
241
  table.dataTable td {
234
242
  box-sizing: border-box;
235
243
  }
244
+ table.dataTable th.dt-type-numeric, table.dataTable th.dt-type-date,
245
+ table.dataTable td.dt-type-numeric,
246
+ table.dataTable td.dt-type-date {
247
+ text-align: right;
248
+ }
236
249
  table.dataTable th.dt-left,
237
250
  table.dataTable td.dt-left {
238
251
  text-align: left;
@@ -258,11 +271,6 @@ table.dataTable td.dt-empty {
258
271
  text-align: center;
259
272
  vertical-align: top;
260
273
  }
261
- table.dataTable th.dt-type-numeric, table.dataTable th.dt-type-date,
262
- table.dataTable td.dt-type-numeric,
263
- table.dataTable td.dt-type-date {
264
- text-align: right;
265
- }
266
274
  table.dataTable thead th,
267
275
  table.dataTable thead td,
268
276
  table.dataTable tfoot th,
@@ -365,6 +373,31 @@ table.table.dataTable.table-hover > tbody > tr.selected:hover > * {
365
373
  box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975);
366
374
  }
367
375
 
376
+ div.dt-container div.dt-layout-start > *:not(:last-child) {
377
+ margin-right: 1em;
378
+ }
379
+ div.dt-container div.dt-layout-end > *:not(:first-child) {
380
+ margin-left: 1em;
381
+ }
382
+ div.dt-container div.dt-layout-full {
383
+ width: 100%;
384
+ }
385
+ div.dt-container div.dt-layout-full > *:only-child {
386
+ margin-left: auto;
387
+ margin-right: auto;
388
+ }
389
+ div.dt-container div.dt-layout-table > div {
390
+ display: block !important;
391
+ }
392
+
393
+ @media screen and (max-width: 767px) {
394
+ div.dt-container div.dt-layout-start > *:not(:last-child) {
395
+ margin-right: 0;
396
+ }
397
+ div.dt-container div.dt-layout-end > *:not(:first-child) {
398
+ margin-left: 0;
399
+ }
400
+ }
368
401
  div.dt-container div.dt-length label {
369
402
  font-weight: normal;
370
403
  text-align: left;
@@ -388,9 +421,6 @@ div.dt-container div.dt-search input {
388
421
  display: inline-block;
389
422
  width: auto;
390
423
  }
391
- div.dt-container div.dt-info {
392
- padding-top: 0.85em;
393
- }
394
424
  div.dt-container div.dt-paging {
395
425
  margin: 0;
396
426
  }