mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-11 02:23:19 -04:00
SCSS refactor, theme cleanup
This commit is contained in:
@@ -228,9 +228,9 @@
|
|||||||
|
|
||||||
var userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
var userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
|
||||||
var url = type === 'service'
|
var url = (type === 'service' ?
|
||||||
? `/services/${currentServiceId}/daily-stats.json?timezone=${encodeURIComponent(userTimezone)}`
|
`/services/${currentServiceId}/daily-stats.json?timezone=${encodeURIComponent(userTimezone)}` :
|
||||||
: `/services/${currentServiceId}/daily-stats-by-user.json?timezone=${encodeURIComponent(userTimezone)}`;
|
`/services/${currentServiceId}/daily-stats-by-user.json?timezone=${encodeURIComponent(userTimezone)}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@@ -292,20 +292,20 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function startPolling() {
|
var startPolling = function() {
|
||||||
fetchData(currentType);
|
fetchData(currentType);
|
||||||
|
|
||||||
pollInterval = setInterval(() => {
|
pollInterval = setInterval(() => {
|
||||||
fetchData(currentType);
|
fetchData(currentType);
|
||||||
}, POLL_INTERVAL_MS);
|
}, POLL_INTERVAL_MS);
|
||||||
}
|
};
|
||||||
|
|
||||||
function stopPolling() {
|
var stopPolling = function() {
|
||||||
if (pollInterval) {
|
if (pollInterval) {
|
||||||
clearInterval(pollInterval);
|
clearInterval(pollInterval);
|
||||||
pollInterval = null;
|
pollInterval = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', () => {
|
document.addEventListener('visibilitychange', () => {
|
||||||
if (document.hidden) {
|
if (document.hidden) {
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
|
|
||||||
// Determine button label
|
// Determine button label
|
||||||
const isMultiple = name !== thing;
|
const isMultiple = name !== thing;
|
||||||
const buttonLabel = isMultiple
|
const buttonLabel = (isMultiple ?
|
||||||
? `Copy ${thing}`
|
`Copy ${thing}` :
|
||||||
: `Copy ${thing} to clipboard`;
|
`Copy ${thing} to clipboard`);
|
||||||
const srSuffix = isMultiple ? ` for ${name}` : '';
|
const srSuffix = isMultiple ? ` for ${name}` : '';
|
||||||
|
|
||||||
// Create simple HTML structure
|
// Create simple HTML structure
|
||||||
|
|||||||
@@ -27,10 +27,11 @@
|
|||||||
var modules = this.find(container);
|
var modules = this.find(container);
|
||||||
|
|
||||||
for (var i = 0, l = modules.length; i < l; i++) {
|
for (var i = 0, l = modules.length; i < l; i++) {
|
||||||
|
var type;
|
||||||
try {
|
try {
|
||||||
var module;
|
var module;
|
||||||
var element = modules[i];
|
var element = modules[i];
|
||||||
var type = this.camelCaseAndCapitalise(element.dataset.module);
|
type = this.camelCaseAndCapitalise(element.dataset.module);
|
||||||
var started = element.dataset.moduleStarted;
|
var started = element.dataset.moduleStarted;
|
||||||
|
|
||||||
if (typeof window.NotifyModules[type] === 'function' && !started) {
|
if (typeof window.NotifyModules[type] === 'function' && !started) {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
@use 'uswds-core' as *;
|
||||||
|
.usa-banner__header-action {
|
||||||
|
font-size: size('body', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.usa-nav__primary > .usa-nav__primary-item > a.usa-nav__link {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usa-section--dark h1 {
|
||||||
|
color: color('blue-30v');
|
||||||
|
@include at-media-max('desktop') {
|
||||||
|
font-size: size('body', 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
.list li {
|
||||||
|
font-family: family('sans');
|
||||||
|
font-size: size('body', 6);
|
||||||
|
}
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
@use "uswds-core" as *;
|
|
||||||
|
|
||||||
$delivered: color('blue-50v');
|
|
||||||
$pending: color('green-cool-40v');
|
|
||||||
$failed: color('gray-cool-20');
|
|
||||||
|
|
||||||
.chart-container {
|
|
||||||
display: flex;
|
|
||||||
&.usage {
|
|
||||||
height: units(4);
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#totalMessageChartContainer {
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar {
|
|
||||||
border-radius: units(0.5);
|
|
||||||
&.delivered, &.usage {
|
|
||||||
background-color: $delivered;
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
&.pending{
|
|
||||||
background-color: $pending;
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
&.failed, &.remaining {
|
|
||||||
background-color: $failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend {
|
|
||||||
display: flex;
|
|
||||||
margin: units(1) 0;
|
|
||||||
.legend-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-right: units(2);
|
|
||||||
}
|
|
||||||
.legend-color {
|
|
||||||
width: units(3);
|
|
||||||
height: units(3);
|
|
||||||
margin-right: 0;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: $delivered;
|
|
||||||
&.pending {
|
|
||||||
background-color: $pending;
|
|
||||||
}
|
|
||||||
&.failed, &.remaining {
|
|
||||||
background-color: $failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.legend-value {
|
|
||||||
margin: 0 units(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
width: 300px;
|
|
||||||
height: 20px;
|
|
||||||
background-color: #eee;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar-inner {
|
|
||||||
height: 100%;
|
|
||||||
background-color: #007bff;
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: units(1) units(1) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-subtitle {
|
|
||||||
font-size: size("body", 6);
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.axis text {
|
|
||||||
font-size: size("body", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.axis line,
|
|
||||||
.axis path {
|
|
||||||
shape-rendering: crispEdges;
|
|
||||||
stroke: #000;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar {
|
|
||||||
fill-opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-container {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-legend {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: units(2);
|
|
||||||
.legend-rect {
|
|
||||||
width: units(2);
|
|
||||||
height: units(2);
|
|
||||||
margin-right: units(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#tooltip {
|
|
||||||
position: absolute;
|
|
||||||
display: none;
|
|
||||||
background: color('ink');
|
|
||||||
color: #FFF;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: units(1);
|
|
||||||
border-radius: units(1);
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 100;
|
|
||||||
font-size: size("body", 3);
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&.usage {
|
&.usage {
|
||||||
height: units(4);
|
height: units(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bar {
|
.bar {
|
||||||
border-radius: units(0.5);
|
border-radius: units(1);
|
||||||
|
|
||||||
&.delivered,
|
&.delivered,
|
||||||
&.usage {
|
&.usage {
|
||||||
@@ -42,12 +42,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: units(1) 0;
|
margin: units(1) 0;
|
||||||
|
|
||||||
.legend-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-right: units(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend-color {
|
.legend-color {
|
||||||
width: units(3);
|
width: units(3);
|
||||||
height: units(3);
|
height: units(3);
|
||||||
@@ -88,10 +82,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.legend .legend-item {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
width: 300px;
|
width: units('card');
|
||||||
height: 20px; // Specific design requirement
|
height: units(3); // Specific design requirement
|
||||||
background-color: color('gray-5');
|
background-color: color('gray-cool-5');
|
||||||
border-radius: units(1);
|
border-radius: units(1);
|
||||||
margin-bottom: units(2);
|
margin-bottom: units(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
&-alternate-link {
|
&-alternate-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
line-height: 35px; // Specific design requirement
|
line-height: units(4); // Specific design requirement
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
.page-footer {
|
.page-footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 30px; // Specific design requirement
|
margin-bottom: units(4); // Specific design requirement
|
||||||
|
|
||||||
&-link {
|
&-link {
|
||||||
line-height: 40px; // Specific design requirement
|
line-height: units(5); // Specific design requirement
|
||||||
padding: 1px 0 0 units(2);
|
padding: 1px 0 0 units(2);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
padding: units(2);
|
padding: units(2);
|
||||||
background: color('gray-cool-10');
|
background: color('gray-cool-10');
|
||||||
border: 1px solid color('gray-cool-10');
|
border: 1px solid color('gray-cool-10');
|
||||||
border-radius: units(0.5);
|
border-radius: units(1);
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
margin: 0 0 units(1) 0;
|
margin: 0 0 units(1) 0;
|
||||||
clear: both;
|
clear: both;
|
||||||
@@ -49,17 +49,17 @@
|
|||||||
.sms-message-file-name,
|
.sms-message-file-name,
|
||||||
.sms-message-scheduler,
|
.sms-message-scheduler,
|
||||||
.sms-message-template {
|
.sms-message-template {
|
||||||
margin: units(0.5) 0 0;
|
margin: units(1) 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sms-message-recipient {
|
.sms-message-recipient {
|
||||||
color: color('gray-cool-90');
|
color: color('gray-cool-90');
|
||||||
margin: units(0.5) 0 units(2);
|
margin: units(1) 0 units(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sms-message-status {
|
.sms-message-status {
|
||||||
color: color('gray-cool-90');
|
color: color('gray-cool-90');
|
||||||
margin: -20px units(1) 20px units(1); // Specific spacing requirement
|
margin: units('neg-205') units(1) units('205') units(1); // Specific spacing requirement
|
||||||
}
|
}
|
||||||
|
|
||||||
.sms-message-status-outbound {
|
.sms-message-status-outbound {
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
h2.sms-message-header {
|
h2.sms-message-header {
|
||||||
margin-bottom: units(0.5);
|
margin-bottom: units(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.usa-prose > * + h2.message-header {
|
.usa-prose > * + h2.message-header {
|
||||||
@@ -75,7 +75,7 @@ h2.sms-message-header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h2.recipient-list {
|
h2.recipient-list {
|
||||||
margin-bottom: units(0.5);
|
margin-bottom: units(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sms-message-row {
|
.sms-message-row {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
td {
|
td {
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
min-width: $spreadsheet-column-width - $spreadsheet-column-padding;
|
min-width: calc(#{$spreadsheet-column-width} - #{$spreadsheet-column-padding});
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: units(0.5);
|
width: units(1);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: $z-index-fullscreen-shadow;
|
z-index: $z-index-fullscreen-shadow;
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-scrolled-table {
|
&-scrolled-table {
|
||||||
padding-bottom: 20px; // Specific design requirement
|
padding-bottom: units(3); // Specific design requirement
|
||||||
|
|
||||||
.table-field-heading-first,
|
.table-field-heading-first,
|
||||||
.table-field-index {
|
.table-field-index {
|
||||||
@@ -168,11 +168,11 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
margin-bottom: 30px; // Specific design requirement
|
margin-bottom: units(4); // Specific design requirement
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
& + .table-show-more-link {
|
& + .table-show-more-link {
|
||||||
margin-top: -20px; // Specific design requirement
|
margin-top: units('neg-3'); // Specific design requirement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
@use 'uswds-core' as *;
|
||||||
|
.usa-banner__header-action {
|
||||||
|
font-size: size('body', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.usa-nav__primary > .usa-nav__primary-item > a.usa-nav__link {
|
||||||
|
font-size: size('body', 5);
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usa-section--dark h1 {
|
||||||
|
color: color('blue-30v');
|
||||||
|
@include at-media-max('desktop') {
|
||||||
|
font-size: size('body', 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
.list li {
|
||||||
|
font-family: family('sans');
|
||||||
|
font-size: size('body', 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.large-number {
|
||||||
|
font-size: size('body', 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-footer .usa-link,
|
||||||
|
.template-content-count,
|
||||||
|
.table-empty-message,
|
||||||
|
td.table-empty-message {
|
||||||
|
font-size: size('body', 'sm');
|
||||||
|
}
|
||||||
|
|
||||||
|
.textbox-highlight-background,
|
||||||
|
.textbox-highlight-foreground,
|
||||||
|
.textbox-highlight-mask,
|
||||||
|
.textbox-highlight-textbox {
|
||||||
|
font-size: units(2);
|
||||||
|
line-height: 1.2;
|
||||||
|
padding: units(1);
|
||||||
|
font-family: family('sans');
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
font-size: size('body', 'sm');
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
@@ -1,5 +1,33 @@
|
|||||||
@use 'uswds-core' as *;
|
@use 'uswds-core' as *;
|
||||||
|
|
||||||
|
// Fix nav container to maintain content width but extend border
|
||||||
|
.usa-header--extended {
|
||||||
|
.usa-nav {
|
||||||
|
@include at-media('desktop') {
|
||||||
|
border-top: 1px solid color('gray-cool-10');
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
// Extend border beyond container
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 100vw;
|
||||||
|
height: 1px;
|
||||||
|
background-color: color('gray-cool-10');
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.usa-nav-container {
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.usa-header--extended .usa-logo {
|
.usa-header--extended .usa-logo {
|
||||||
font-family: family('sans');
|
font-family: family('sans');
|
||||||
margin: units(3) 0;
|
margin: units(3) 0;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
@use 'uswds-core' as *;
|
||||||
|
|
||||||
|
.usa-nav__primary {
|
||||||
|
& > .usa-nav__primary-item > a {
|
||||||
|
font-size: size('body', 5);
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@include at-media('desktop') {
|
||||||
|
line-height: 1;
|
||||||
|
padding: units(2);
|
||||||
|
align-items: center;
|
||||||
|
color: color('gray-cool-60');
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .usa-nav__primary-item {
|
||||||
|
@include at-media('desktop') {
|
||||||
|
font-size: size('body', 3);
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,15 +14,15 @@ $z-index-fullscreen-header: 200;
|
|||||||
$z-index-spreadsheet-fixed: 1000;
|
$z-index-spreadsheet-fixed: 1000;
|
||||||
|
|
||||||
// SMS message bubbles
|
// SMS message bubbles
|
||||||
$sms-bubble-max-width: 464px;
|
$sms-bubble-max-width: units('mobile'); // ~464px
|
||||||
$sms-bubble-arrow-size: 10px;
|
$sms-bubble-arrow-size: units('105'); // ~10px
|
||||||
$sms-bubble-arrow-width: 13px;
|
$sms-bubble-arrow-width: units(2); // ~13px
|
||||||
$sms-bubble-arrow-offset: 20px;
|
$sms-bubble-arrow-offset: units('205'); // ~20px
|
||||||
$sms-bubble-arrow-rotation: 17deg;
|
$sms-bubble-arrow-rotation: 17deg;
|
||||||
|
|
||||||
// Spreadsheet viewer
|
// Spreadsheet viewer
|
||||||
$spreadsheet-column-width: 194px;
|
$spreadsheet-column-width: 194px; // Keep as pixels for specific layout requirement
|
||||||
$spreadsheet-column-padding: 11px;
|
$spreadsheet-column-padding: 16px; // Keep as pixels for calc compatibility
|
||||||
$spreadsheet-scrollbar-height: 11px;
|
$spreadsheet-scrollbar-height: units(2); // ~11px
|
||||||
$spreadsheet-scrollbar-thumb-radius: units(1);
|
$spreadsheet-scrollbar-thumb-radius: units(1);
|
||||||
$spreadsheet-scrollbar-border: 2px;
|
$spreadsheet-scrollbar-border: 2px; // Keep as pixels for webkit scrollbar
|
||||||
|
|||||||
@@ -1,15 +1,27 @@
|
|||||||
|
// Load USWDS theme configuration first
|
||||||
@forward "uswds-theme";
|
@forward "uswds-theme";
|
||||||
|
|
||||||
|
// Then load USWDS which will use the theme settings
|
||||||
@forward "uswds";
|
@forward "uswds";
|
||||||
|
|
||||||
|
// Custom tokens
|
||||||
@forward "settings/tokens";
|
@forward "settings/tokens";
|
||||||
|
|
||||||
|
// Components
|
||||||
@forward "components/sms-message";
|
@forward "components/sms-message";
|
||||||
@forward "components/file-upload";
|
@forward "components/file-upload";
|
||||||
@forward "components/spreadsheet";
|
@forward "components/spreadsheet";
|
||||||
@forward "components/charts";
|
@forward "components/charts";
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
@forward "utilities/utilities";
|
||||||
|
|
||||||
// USWDS overrides
|
// USWDS overrides
|
||||||
|
@forward "overrides/typography";
|
||||||
@forward "overrides/usa-header";
|
@forward "overrides/usa-header";
|
||||||
|
@forward "overrides/usa-nav";
|
||||||
@forward "overrides/usa-search";
|
@forward "overrides/usa-search";
|
||||||
@forward "overrides/modal";
|
@forward "overrides/modal";
|
||||||
|
|
||||||
|
// Custom overrides that MUST come last to override USWDS defaults
|
||||||
|
@use "custom-overrides";
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
@use 'uswds-core' as *;
|
||||||
|
|
||||||
|
// Utility classes to replace inline styles
|
||||||
|
.text-error {
|
||||||
|
color: color('red-60v');
|
||||||
|
}
|
||||||
|
|
||||||
|
.width-half {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width-quarter {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-js-toggle {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.no-js & {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.js-enabled-toggle {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.js-enabled & {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.visibility-hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-spaced {
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
@@ -78,7 +78,9 @@ def get_organization_message_allowance(org_id):
|
|||||||
|
|
||||||
def get_services_dashboard_data(organization, year):
|
def get_services_dashboard_data(organization, year):
|
||||||
try:
|
try:
|
||||||
dashboard_data = organizations_client.get_organization_dashboard(organization.id, year)
|
dashboard_data = organizations_client.get_organization_dashboard(
|
||||||
|
organization.id, year
|
||||||
|
)
|
||||||
services = dashboard_data.get("services", [])
|
services = dashboard_data.get("services", [])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(f"Error fetching dashboard data: {e}")
|
current_app.logger.error(f"Error fetching dashboard data: {e}")
|
||||||
@@ -100,7 +102,9 @@ def get_services_dashboard_data(organization, year):
|
|||||||
usage_parts.append(f"{emails_sent:,} emails")
|
usage_parts.append(f"{emails_sent:,} emails")
|
||||||
if sms_sent > 0 or sms_remainder > 0:
|
if sms_sent > 0 or sms_remainder > 0:
|
||||||
if sms_cost > 0:
|
if sms_cost > 0:
|
||||||
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})")
|
usage_parts.append(
|
||||||
|
f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining)")
|
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining)")
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
{% block bodyStart %}
|
{% block bodyStart %}
|
||||||
{% block extra_javascripts_before_body %}
|
{% block extra_javascripts_before_body %}
|
||||||
<noscript><iframe sandbox src="https://www.googletagmanager.com/ns.html?id=GTM-WX5NGWF"
|
<noscript><iframe sandbox src="https://www.googletagmanager.com/ns.html?id=GTM-WX5NGWF"
|
||||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
height="0" width="0" class="display-none visibility-hidden"></iframe></noscript>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="usa-nav__secondary margin-bottom-6">
|
<div class="usa-nav__secondary">
|
||||||
<ul class="usa-nav__secondary-links">
|
<ul class="usa-nav__secondary-links">
|
||||||
{% if secondaryNavigation %}
|
{% if secondaryNavigation %}
|
||||||
{% for item in secondaryNavigation %}
|
{% for item in secondaryNavigation %}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{{ usaInsetText({
|
{{ usaInsetText({
|
||||||
"html": '<p class="usa-body">First paragraph</p>
|
"html": '<p class="usa-body">First paragraph</p>
|
||||||
<p class="usa-body" style="letter-spacing: 1px;">---</p>
|
<p class="usa-body text-spaced">---</p>
|
||||||
<p class="usa-body">Second paragraph</p>',
|
<p class="usa-body">Second paragraph</p>',
|
||||||
"classes": ""})
|
"classes": ""})
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{{ usaButton({
|
{{ usaButton({
|
||||||
"element": "a",
|
"element": "a",
|
||||||
"text": "Add a new service",
|
"text": "Add service",
|
||||||
"href": url_for('.add_service'),
|
"href": url_for('.add_service'),
|
||||||
"classes": ""
|
"classes": ""
|
||||||
}) }}
|
}) }}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.failed_login_count > 0 %}
|
{% if user.failed_login_count > 0 %}
|
||||||
<p style="color:#b10e1e;">
|
<p class="text-error">
|
||||||
{{ user.failed_login_count }} failed login attempts
|
{{ user.failed_login_count }} failed login attempts
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<div>
|
<div>
|
||||||
{{ live_search(target_selector='.user-list-item', show=True, form=form) }}
|
{{ live_search(target_selector='.user-list-item', show=True, form=form) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="js-live-search-no-results" style="display: none;">
|
<div class="js-live-search-no-results display-none">
|
||||||
<p class="usa-body margin-0">No results found</p>
|
<p class="usa-body margin-0">No results found</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import usaButton %} {% block meta %}
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="usa-section usa-prose" aria-label="Introduction">
|
<section class="usa-section usa-prose" aria-label="Introduction">
|
||||||
<div class="grid-container padding-y-4">
|
<div class="grid-container">
|
||||||
<div class="grid-row grid-gap display-flex flex-align-center">
|
<div class="grid-row grid-gap display-flex flex-align-center">
|
||||||
<div class="desktop:grid-col-8 tablet:grid-col-12">
|
<div class="desktop:grid-col-8 tablet:grid-col-12">
|
||||||
<h2 class="font-body-xl">
|
<h2 class="font-body-xl">
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
form=search_form,
|
form=search_form,
|
||||||
autofocus=True
|
autofocus=True
|
||||||
) }}
|
) }}
|
||||||
<div class="js-live-search-no-results" style="display: none;">
|
<div class="js-live-search-no-results display-none">
|
||||||
<p class="usa-body margin-top-2">No templates found</p>
|
<p class="usa-body margin-top-2">No templates found</p>
|
||||||
</div>
|
</div>
|
||||||
<nav id="template-list" aria-label="Copy template list">
|
<nav id="template-list" aria-label="Copy template list">
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
const { urls, baseUrl } = require('./urls');
|
const { urls, baseUrl } = require('./urls');
|
||||||
|
|
||||||
const MISMATCH_THRESHOLD = .2;
|
const MISMATCH_THRESHOLD = .3;
|
||||||
const SCREENSHOT_DELAY = 2000;
|
const SCREENSHOT_DELAY = 2000;
|
||||||
|
|
||||||
const createScenariosFromUrls = (urls, delay = SCREENSHOT_DELAY) => {
|
const createScenariosFromUrls = (urls, delay = SCREENSHOT_DELAY) => {
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ def test_choose_account_should_show_choose_accounts_page_if_no_services(
|
|||||||
assert len(links) == 1
|
assert len(links) == 1
|
||||||
add_service_link = links[0]
|
add_service_link = links[0]
|
||||||
assert normalize_spaces(page.h1.text) == "Choose service"
|
assert normalize_spaces(page.h1.text) == "Choose service"
|
||||||
assert normalize_spaces(add_service_link.text) == "Add a new service"
|
assert normalize_spaces(add_service_link.text) == "Add service"
|
||||||
assert not page.select("main h2")
|
assert not page.select("main h2")
|
||||||
assert add_service_link["href"] == url_for("main.add_service")
|
assert add_service_link["href"] == url_for("main.add_service")
|
||||||
|
|
||||||
|
|||||||
@@ -1585,9 +1585,24 @@ def test_organization_dashboard_shows_service_counts(
|
|||||||
"app.organizations_client.get_organization_dashboard",
|
"app.organizations_client.get_organization_dashboard",
|
||||||
return_value={
|
return_value={
|
||||||
"services": [
|
"services": [
|
||||||
{"service_id": "1", "service_name": "Live Service", "active": True, "restricted": False},
|
{
|
||||||
{"service_id": "2", "service_name": "Trial Service", "active": True, "restricted": True},
|
"service_id": "1",
|
||||||
{"service_id": "3", "service_name": "Suspended", "active": False, "restricted": False},
|
"service_name": "Live Service",
|
||||||
|
"active": True,
|
||||||
|
"restricted": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service_id": "2",
|
||||||
|
"service_name": "Trial Service",
|
||||||
|
"active": True,
|
||||||
|
"restricted": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service_id": "3",
|
||||||
|
"service_name": "Suspended",
|
||||||
|
"active": False,
|
||||||
|
"restricted": False,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -1615,11 +1630,17 @@ def test_organization_dashboard_services_table(
|
|||||||
mocker,
|
mocker,
|
||||||
active_user_with_permissions,
|
active_user_with_permissions,
|
||||||
):
|
):
|
||||||
mocker.patch.dict("flask.current_app.config", {"ORGANIZATION_DASHBOARD_ENABLED": True})
|
mocker.patch.dict(
|
||||||
|
"flask.current_app.config", {"ORGANIZATION_DASHBOARD_ENABLED": True}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
"app.organizations_client.get_organization_message_usage",
|
"app.organizations_client.get_organization_message_usage",
|
||||||
return_value={"messages_sent": 0, "messages_remaining": 0, "total_message_limit": 0},
|
return_value={
|
||||||
|
"messages_sent": 0,
|
||||||
|
"messages_remaining": 0,
|
||||||
|
"total_message_limit": 0,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
"app.organizations_client.get_organization_services",
|
"app.organizations_client.get_organization_services",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ def test_non_gov_user_cannot_see_add_service_button(
|
|||||||
):
|
):
|
||||||
client_request.login(api_nongov_user_active)
|
client_request.login(api_nongov_user_active)
|
||||||
page = client_request.get("main.choose_account")
|
page = client_request.get("main.choose_account")
|
||||||
assert "Add a new service" not in page.text
|
assert "Add service" not in page.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ def e2e_created_service(e2e_test_service): # noqa: PT022
|
|||||||
page.goto(f"{E2E_TEST_URI}/accounts")
|
page.goto(f"{E2E_TEST_URI}/accounts")
|
||||||
page.wait_for_load_state("domcontentloaded")
|
page.wait_for_load_state("domcontentloaded")
|
||||||
|
|
||||||
add_service_button = page.get_by_role("button", name="Add a new service")
|
add_service_button = page.get_by_role("button", name="Add service")
|
||||||
add_service_button.click()
|
add_service_button.click()
|
||||||
page.wait_for_load_state("domcontentloaded")
|
page.wait_for_load_state("domcontentloaded")
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ def test_add_new_service_workflow(e2e_test_service):
|
|||||||
expect(sign_in_heading).to_be_visible()
|
expect(sign_in_heading).to_be_visible()
|
||||||
|
|
||||||
# Retrieve some prominent elements on the page for testing.
|
# Retrieve some prominent elements on the page for testing.
|
||||||
add_service_button = page.get_by_role(
|
add_service_button = page.get_by_role("button", name=re.compile("Add service"))
|
||||||
"button", name=re.compile("Add a new service")
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(add_service_button).to_be_visible()
|
expect(add_service_button).to_be_visible()
|
||||||
|
|
||||||
|
|||||||
@@ -119,9 +119,7 @@ def test_create_new_template(end_to_end_context):
|
|||||||
expect(sign_in_heading).to_be_visible()
|
expect(sign_in_heading).to_be_visible()
|
||||||
|
|
||||||
# Retrieve some prominent elements on the page for testing.
|
# Retrieve some prominent elements on the page for testing.
|
||||||
add_service_button = page.get_by_role(
|
add_service_button = page.get_by_role("button", name=re.compile("Add service"))
|
||||||
"button", name=re.compile("Add a new service")
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(add_service_button).to_be_visible()
|
expect(add_service_button).to_be_visible()
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ def _setup(page):
|
|||||||
expect(sign_in_heading).to_be_visible()
|
expect(sign_in_heading).to_be_visible()
|
||||||
|
|
||||||
# Retrieve some prominent elements on the page for testing.
|
# Retrieve some prominent elements on the page for testing.
|
||||||
add_service_button = page.get_by_role(
|
add_service_button = page.get_by_role("button", name=re.compile("Add service"))
|
||||||
"button", name=re.compile("Add a new service")
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(add_service_button).to_be_visible()
|
expect(add_service_button).to_be_visible()
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ def _setup(page):
|
|||||||
expect(sign_in_heading).to_be_visible()
|
expect(sign_in_heading).to_be_visible()
|
||||||
|
|
||||||
# Retrieve some prominent elements on the page for testing.
|
# Retrieve some prominent elements on the page for testing.
|
||||||
add_service_button = page.get_by_role(
|
add_service_button = page.get_by_role("button", name=re.compile("Add service"))
|
||||||
"button", name=re.compile("Add a new service")
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(add_service_button).to_be_visible()
|
expect(add_service_button).to_be_visible()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user