Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6eaf4de
Begin template upgrade work
susanna-carey Feb 2, 2026
eac6768
Continue work on template updates to template.
susanna-carey Feb 3, 2026
08fd1dc
Revert change on prepend and continue work on bs 5 upgrade
susanna-carey Feb 3, 2026
8af90ef
Update query-form.hbs
susanna-carey Feb 3, 2026
039aed6
Update errors.md
susanna-carey Feb 4, 2026
1123e1f
Fix issue with losing link underline on hover.
susanna-carey Feb 4, 2026
cf4da57
Continue work updating bootstrap 4 to 5 classes clean up.
susanna-carey Feb 4, 2026
70ea651
Work on updating form labels from bs 4 to 5.
susanna-carey Feb 4, 2026
e42f377
Fix issue with nav layout.
susanna-carey Feb 5, 2026
9c6e740
Fix spacing
susanna-carey Feb 5, 2026
0b01813
Merge branch 'main' into bootstrap-template-upgrades
susanna-carey Feb 5, 2026
1522f4d
Fix issue with broken active class in nav dropdown menu
susanna-carey Feb 9, 2026
4bd05ed
Update datatables to version 5 to match bootstrap 5
susanna-carey Feb 9, 2026
d42c449
Add replacement link for Lucene's formula and clean up _tables.scss file
susanna-carey Feb 9, 2026
a2be248
Update _base.scss
susanna-carey Feb 9, 2026
2f7cf3b
Fix broken popover.
susanna-carey Feb 10, 2026
0235f71
Continued work on bootstrap 5 upgrades.
susanna-carey Feb 10, 2026
21c5583
Fix linter issues.
susanna-carey Feb 11, 2026
3dc4228
Add note to ChangeLog about the bootstrap upgrade.
susanna-carey Feb 11, 2026
ac8de06
Merge remote-tracking branch 'origin/main' into bootstrap-template-up…
GUI Feb 18, 2026
e88b695
WIP: Bootstrap upgrade tweaks and fixes.
GUI Feb 19, 2026
7b5201a
More WIP
GUI Feb 20, 2026
0acee80
WIP
GUI Feb 21, 2026
0de51a0
Fix build.
GUI Feb 21, 2026
d666fc1
Merge remote-tracking branch 'origin/main' into bootstrap-template-up…
GUI Apr 3, 2026
2cb7e33
Merge remote-tracking branch 'origin/bootstrap-template-upgrades-twea…
GUI Apr 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ If you're upgrading a previous API Umbrella version, you may upgrade the `api-um

- **Route API backend requests directly from Traffic Server:** Routing to API backends has been simplified so it occurs directly from Traffic Server, instead of routing back through an extra nginx hop. This should improve efficiency, simplifies routing, and eliminates DNS-related code. ([#410](https://github.com/NREL/api-umbrella/pull/410))
- **Admin UI Upgrades:** Upgrade the admin UI project from Ember 2.8 to Ember 3.9 and Bootstrap 3 to Bootstrap 4. This switch also moves all dependencies into NPM instead of Bower, and better uses ES6 syntax throughout the admin UI code. Integration tests have also been switched from PhantomJS to Selenium tests using headless Chrome. ([#429](https://github.com/NREL/api-umbrella/pull/429), [api.data.gov#434](https://github.com/18F/api.data.gov/issues/434))
- **Bootstrap upgrade:** Bootstrap upgrade for admin UI project from Bootstrap version 4 to 5.3 (02/2026)
- **Upgrade to GeoIP2 database:** The legacy GeoIP data previously being used has been discontinued, so GeoIP2 is now being used for geo-locating IP addresses. ([8f17dae](https://github.com/NREL/api-umbrella/commit/8f17dae991de7553cb67ee319392bf53c17a5083), [#440](https://github.com/NREL/api-umbrella/issues/440))
- **Redirect all website content to HTTPS by default:** All website requests now redirect to HTTPS by default. ([b3a8abc](https://github.com/NREL/api-umbrella/commit/b3a8abc81347cbeb274e00f40fcfccea3af1b546), [#407](https://github.com/NREL/api-umbrella/issues/407), [api.data.gov#430](https://github.com/18F/api.data.gov/issues/430))
- **Improve HTTPS requirements for API requests to error earlier:** When making an insecure API request, return an error about HTTPS being required before the API key requirement error. ([api.data.gov#454](https://github.com/18F/api.data.gov/issues/454))
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ COPY tasks/app/example-website/build /app/tasks/app/example-website/
RUN make app:example-website:build && make clean:dev

COPY src/api-umbrella/web-app/assets /app/src/api-umbrella/web-app/assets
COPY src/api-umbrella/web-app/webpack.config.js /app/src/api-umbrella/web-app/webpack.config.js
COPY src/api-umbrella/web-app/package.json /app/src/api-umbrella/web-app/package.json
COPY src/api-umbrella/web-app/vite.config.js /app/src/api-umbrella/web-app/vite.config.js
COPY tasks/app/web-app/precompile /app/tasks/app/web-app/
RUN make app:web-app:precompile && make clean:dev

Expand Down
3 changes: 2 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ tasks:
sources:
- ./build/work/stamp/app-deps/web-app/pnpm
- ./src/api-umbrella/web-app/assets/**/*.scss
- ./src/api-umbrella/web-app/webpack.config.js
- ./src/api-umbrella/web-app/package.json
- ./src/api-umbrella/web-app/vite.config.js
- ./tasks/app/web-app/precompile
- ./tasks/helpers.sh
generates:
Expand Down
44 changes: 22 additions & 22 deletions docs/admin/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@ REST API

.. raw:: html

<div class="swagger-section">
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</div>
<div class="swagger-section">
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</div>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/2.1.3/css/screen.min.css" />
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery-1.8.0.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.slideto.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.wiggle.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.ba-bbq.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/handlebars-2.0.0.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/underscore-min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/backbone-min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/swagger-ui.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/highlight.7.3.pack.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/marked.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/swagger-oauth.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/2.1.3/css/screen.min.css" />
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery-1.8.0.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.slideto.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.wiggle.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/jquery.ba-bbq.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/handlebars-2.0.0.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/underscore-min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/backbone-min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/swagger-ui.min.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/highlight.7.3.pack.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/marked.js"></script>
<script src="https://cdn.rawgit.com/swagger-api/swagger-ui/v2.1.3/dist/lib/swagger-oauth.js"></script>

<script type="text/javascript">
window.swaggerUi = new SwaggerUi({
url: '../../_static/admin-api-swagger.yml',
dom_id: 'swagger-ui-container'
});
<script type="text/javascript">
window.swaggerUi = new SwaggerUi({
url: '../../_static/admin-api-swagger.yml',
dom_id: 'swagger-ui-container'
});

window.swaggerUi.load();
</script>
window.swaggerUi.load();
</script>
14 changes: 0 additions & 14 deletions src/api-umbrella/admin-ui/app/components/api-users/record-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,6 @@ export default class RecordForm extends Component.extend(Save) {

return message;
},
messageHide(model) {
if(isNew && model.get('apiKey')) {
return false;
} else {
return true;
}
},
messageWidth(model) {
if(isNew && model.get('apiKey')) {
return '500px';
} else {
return undefined;
}
},
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Component from '@ember/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { tagName } from '@ember-decorators/component';
import Sortable from 'api-umbrella-admin-ui/utils/sortable';
import bootbox from 'bootbox';
import classic from 'ember-classic-decorator';
import without from 'lodash-es/without';
Expand All @@ -15,12 +14,6 @@ export default class RewriteTable extends Component {

openModal = false;

init() {
super.init(...arguments);

this.sortable = new Sortable(this.model.rewrites);
}

@action
add() {
this.set('rewriteModel', this.store.createRecord('api/rewrite'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Component from '@ember/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { tagName } from '@ember-decorators/component';
import Sortable from 'api-umbrella-admin-ui/utils/sortable';
import bootbox from 'bootbox';
import classic from 'ember-classic-decorator';
import without from 'lodash-es/without';
Expand All @@ -15,12 +14,6 @@ export default class SubSettingsTable extends Component {

openModal = false;

init() {
super.init(...arguments);

this.sortable = new Sortable(this.model.subSettings);
}

@action
add() {
this.set('subSettingsModel', this.store.createRecord('api/sub-settings'));
Expand Down
11 changes: 7 additions & 4 deletions src/api-umbrella/admin-ui/app/components/config/publish-form.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// eslint-disable-next-line ember/no-classic-components
import Component from '@ember/component';
import { action, computed } from '@ember/object';
import { success } from '@pnotify/core';
import { service } from '@ember/service';
import LoadingButton from 'api-umbrella-admin-ui/utils/loading-button';
import bootbox from 'bootbox';
import Diff from 'diff';
Expand All @@ -12,6 +12,8 @@ import $ from 'jquery';
export default class PublishForm extends Component {
tagName = '';

@service pendingFlashMessages;

@action
didInsert(element) {
this.publishButton = element.querySelector('.publish-button');
Expand Down Expand Up @@ -121,10 +123,11 @@ export default class PublishForm extends Component {
data: form.serialize(),
}).then(() => {
LoadingButton.reset(this.publishButton);
success({

this.pendingFlashMessages.add({
type: 'success',
title: 'Published',
text: 'Successfully published the configuration<br>Changes should be live in a few seconds...',
textTrusted: true,
message: 'Successfully published the configuration<br>Changes should be live in a few seconds...',
});

this.refreshCurrentRouteController();
Expand Down
6 changes: 6 additions & 0 deletions src/api-umbrella/admin-ui/app/components/flash-messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { service } from '@ember/service';
import Component from '@glimmer/component';

export default class FlashMessages extends Component {
@service currentFlashMessages;
}
103 changes: 103 additions & 0 deletions src/api-umbrella/admin-ui/app/components/reorder-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {RestrictToVerticalAxis} from '@dnd-kit/abstract/modifiers';
import {DragDropManager} from '@dnd-kit/dom';
import {isSortable,Sortable} from '@dnd-kit/dom/sortable';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import { schedule } from '@ember/runloop';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class ReorderTable extends Component {
@tracked isReordering = false;

constructor() {
super(...arguments);
this.setupDomSorting();
}

willDestroy() {
super.willDestroy(...arguments);
this.destroyDomSorting();
}

get isReorderable() {
const length = this.args.collection.length;
this.handleCollectionChange();
return (length > 1);
}

get container() {
const container = document.getElementById(this.args.tableId);
return container;
}

handleCollectionChange() {
schedule('afterRender', this, function() {
this.setupDomSorting();
});
}

@action
toggleReordering() {
this.isReordering = !this.isReordering;
this.setupDomSorting();
}

setupDomSorting() {
this.destroyDomSorting();

if(!this.container) {
console.error('tableId doesn not exist: ', this.args.tableId);
return;
}

if(this.isReordering) {
this.container.classList.add('reorder-active');
} else {
this.container.classList.remove('reorder-active');
}

this.manager = new DragDropManager({
modifiers: (defaults) => [...defaults, RestrictToVerticalAxis],
});

this.sortables = [];
const tableRowEls = this.container.querySelectorAll('tbody tr');
for(const [index, tableRowEl] of tableRowEls.entries()) {
this.sortables.push(new Sortable({
id: tableRowEl.dataset.guid,
index,
element: tableRowEl,
handle: tableRowEl.querySelector('.reorder-handle'),
}, this.manager));
}

this.manager.monitor.addEventListener('dragend', this.handleDragEnd.bind(this));
}

destroyDomSorting() {
if(this.manager) {
this.manager.destroy();
}
}

handleDragEnd(event) {
if(event.canceled || !isSortable(event.operation.source)) {
return;
}

const indexes = {};
for(const sortable of this.sortables) {
indexes[sortable.id] = sortable.index;
}

this.updateCollectionSortOrders(indexes);
}

updateCollectionSortOrders(indexes) {
for(const record of this.args.collection) {
const index = indexes[guidFor(record)];
record.set('sortOrder', index + 1);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export default class ResultsTable extends Component {
render: (name, type, data) => {
if(type === 'display' && name && name !== '-') {
if(data.terminal) {
return '<i class="far fa-file fa-fw mr-1"></i>' + escape(name);
return '<i class="far fa-file me-1"></i>' + escape(name);
} else {
let params = clone(this.presentQueryParamValues);
params.prefix = data.descendent_prefix;
let link = '#/stats/drilldown?' + $.param(params);

return '<a href="' + link + '"><i class="far fa-folder fa-fw mr-1"></i>' + escape(name) + '</a>';
return '<a href="' + link + '"><i class="far fa-folder me-1"></i>' + escape(name) + '</a>';
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default class ResultsTable extends Component {
theme: 'light-border forced-wide',
arrow: true,
delay: 200,
appendTo: $cell[0],
});
}
});
Expand Down Expand Up @@ -330,7 +331,7 @@ export default class ResultsTable extends Component {
const tooltipButtonEl = document.createElement('button');
tooltipButtonEl.className = 'btn btn-link btn-tooltip';
tooltipButtonEl.type = 'button';
tooltipButtonEl.innerHTML = '<i class="fas fa-question-circle"></i><span class="sr-only">Help</span>';
tooltipButtonEl.innerHTML = '<i class="fas fa-question-circle"></i><span class="visually-hidden">Help</span>';

tippy(tooltipButtonEl, {
trigger: 'click',
Expand Down
29 changes: 28 additions & 1 deletion src/api-umbrella/admin-ui/app/components/stats/query-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import QueryBuilder from 'jQuery-QueryBuilder';
import forEach from 'lodash-es/forEach';
import { marked } from 'marked';
import moment from 'moment-timezone';
import tippy from 'tippy.js';

marked.use({
gfm: true,
Expand All @@ -31,7 +32,7 @@ QueryBuilder.define('filter-description', function() {
if(!buttonEl) {
buttonEl = document.createElement('button');
buttonEl.type = 'button';
buttonEl.className = 'btn btn-sm btn-info filter-description btn-tooltip tooltip-trigger';
buttonEl.className = 'btn btn-sm btn-link border filter-description tooltip-trigger';
buttonEl.innerHTML = '<i class="fas fa-question-circle"></i>';

const ruleActionEl = rule.$el[0].querySelector(QueryBuilder.selectors.rule_actions);
Expand Down Expand Up @@ -474,6 +475,32 @@ export default class QueryForm extends Component {
} else if(this.search) {
this.send('toggleFilterType', 'advanced');
}

const helpTriggerLink = document.querySelector('.lucene-help-link');
const helpContent = document.getElementById('query_syntax_help_content');
if(helpTriggerLink && helpContent) {
this.helpTippy = tippy(helpTriggerLink, {
trigger: 'click',
interactive: true,
theme: 'light-border',
arrow: true,
allowHTML: true,
content: helpContent.innerHTML,
placement: 'bottom-start',
maxWidth: 'none',
// Below the sticky navigation header, since this popover can be so
// large and cause the page to scroll.
zIndex: 1019,
});

}
}

willDestroy() {
if(this.helpTippy) {
this.helpTippy.destroy();
}
super.willDestroy(...arguments);
}

// eslint-disable-next-line ember/no-observers
Expand Down
Loading
Loading