Skip to content

Commit 7406c51

Browse files
author
ci bot
committed
Merge branch 'aarthy/email-empty' into 'enterprise'
fix(emails): add empty state message when smtp server not configured See merge request dkinternal/testgen/dataops-testgen!362
2 parents 05b238c + 91ff18b commit 7406c51

9 files changed

Lines changed: 43 additions & 5 deletions

File tree

testgen/__main__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@
4444
)
4545
from testgen.common.models import with_database_session
4646
from testgen.common.models.profiling_run import ProfilingRun
47+
from testgen.common.models.settings import PersistedSetting
4748
from testgen.common.models.test_run import TestRun
4849
from testgen.common.models.test_suite import TestSuite
50+
from testgen.common.notifications.base import smtp_configured
4951
from testgen.common.notifications.profiling_run import send_profiling_run_notifications
5052
from testgen.common.notifications.test_run import send_test_run_notifications
5153
from testgen.scheduler import register_scheduler_job, run_scheduler
@@ -647,7 +649,7 @@ def run_ui():
647649
patch_streamlit.patch(force=True)
648650

649651
@with_database_session
650-
def cancel_all_running():
652+
def init_ui():
651653
try:
652654
for profiling_run_id in ProfilingRun.cancel_all_running():
653655
send_profiling_run_notifications(ProfilingRun.get(profiling_run_id))
@@ -656,7 +658,9 @@ def cancel_all_running():
656658
except Exception:
657659
LOG.warning("Failed to cancel 'Running' profiling/test runs")
658660

659-
cancel_all_running()
661+
PersistedSetting.set("SMTP_CONFIGURED", smtp_configured())
662+
663+
init_ui()
660664

661665
app_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui/app.py")
662666
process= subprocess.Popen(

testgen/common/models/test_result.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def diff(cls, test_run_id_a: UUID, test_run_id_b: UUID) -> list[TestResultDiffTy
6666
alias_a.test_definition_id == alias_b.test_definition_id,
6767
),
6868
),
69-
isouter=True,
7069
full=True,
7170
).where(
7271
or_(alias_a.test_run_id == test_run_id_a, alias_a.test_run_id.is_(None)),

testgen/common/notifications/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
)
2525

2626

27+
def smtp_configured() -> bool:
28+
return all(getattr(settings, setting_name) is not None for setting_name in MANDATORY_SETTINGS)
29+
30+
2731
class EmailTemplateException(Exception):
2832
pass
2933

testgen/ui/components/frontend/js/components/empty_state.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ const EMPTY_STATE_MESSAGE = {
5454
line1: 'Track data quality scores',
5555
line2: 'Filter or select columns to assess the quality of your data assets across different categories.',
5656
},
57+
notifications: {
58+
line1: '',
59+
line2: 'Configure an SMTP email server for TestGen to get alerts on profiling runs, test runs, and quality scorecards.',
60+
},
5761
};
5862

5963
const EmptyState = (/** @type Properties */ props) => {

testgen/ui/components/frontend/js/pages/notification_settings.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*
2020
* @typedef Properties
2121
* @type {object}
22+
* @property {Boolean} smtp_configured
2223
* @property {String} event
2324
* @property {NotificationItem[]} items
2425
* @property {Permissions} permissions
@@ -39,8 +40,9 @@ import { Alert } from '../components/alert.js';
3940
import { Textarea } from '../components/textarea.js';
4041
import { Icon } from '../components/icon.js';
4142
import { TruncatedText } from '../components/truncated_text.js';
42-
import { Input } from "../components/input.js";
43-
import { numberBetween } from "../form_validators.js";
43+
import { Input } from '../components/input.js';
44+
import { numberBetween } from '../form_validators.js';
45+
import { EmptyState, EMPTY_STATE_MESSAGE } from '../components/empty_state.js';
4446

4547
const minHeight = 500;
4648
const { div, span, b } = van.tags;
@@ -49,6 +51,20 @@ const NotificationSettings = (/** @type Properties */ props) => {
4951
loadStylesheet('notification-settings', stylesheet);
5052
window.testgen.isPage = true;
5153

54+
if (!getValue(props.smtp_configured)) {
55+
Streamlit.setFrameHeight(400);
56+
return EmptyState({
57+
label: 'Email server not configured.',
58+
message: EMPTY_STATE_MESSAGE.notifications,
59+
class: 'notifications--empty',
60+
link: {
61+
label: 'View documentation',
62+
href: 'https://docs.datakitchen.io/articles/dataops-testgen-help/configure-email-server',
63+
open_new: true,
64+
},
65+
});
66+
}
67+
5268
const nsItems = van.derive(() => {
5369
const items = getValue(props.items);
5470
Streamlit.setFrameHeight(Math.max(minHeight, 70 * items.length || 150));
@@ -329,6 +345,9 @@ const NotificationSettings = (/** @type Properties */ props) => {
329345

330346
const stylesheet = new CSSStyleSheet();
331347
stylesheet.replace(`
348+
.notifications--empty.tg-empty-state {
349+
margin-top: 0;
350+
}
332351
.notifications--editing-row {
333352
background-color: var(--select-hover-background);
334353
}

testgen/ui/views/dialogs/manage_notifications.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from testgen.common.models import with_database_session
1010
from testgen.common.models.notification_settings import NotificationSettings, NotificationSettingsValidationError
11+
from testgen.common.models.settings import PersistedSetting
1112
from testgen.ui.components import widgets
1213
from testgen.ui.session import session, temp_value
1314

@@ -121,6 +122,7 @@ def render(self) -> None:
121122
widgets.testgen_component(
122123
"notification_settings",
123124
props={
125+
"smtp_configured": PersistedSetting.get("SMTP_CONFIGURED"),
124126
"items": ns_json_list,
125127
"event": self.ns_class.__mapper_args__["polymorphic_identity"].value,
126128
"permissions": {"can_edit": user_can_edit},

testgen/ui/views/profiling_runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def get_job_arguments(self, arg_value: str) -> tuple[list[typing.Any], dict[str,
128128

129129
class ProfilingRunNotificationSettingsDialog(NotificationSettingsDialogBase):
130130

131+
title = "Profiling Notifications"
132+
131133
def _item_to_model_attrs(self, item: dict[str, typing.Any]) -> dict[str, typing.Any]:
132134
return {
133135
"trigger": ProfilingRunNotificationTrigger(item["trigger"]),

testgen/ui/views/score_details.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ def recalculate_score_history(definition_id: str) -> None:
234234

235235
class ScoreDropNotificationSettingsDialog(NotificationSettingsDialogBase):
236236

237+
title = "Scorecard Notifications"
238+
237239
def _item_to_model_attrs(self, item: dict[str, Any]) -> dict[str, Any]:
238240
model_data = {
239241
attr: Decimal(item[attr])

testgen/ui/views/test_runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ def open_dialog(*_):
125125

126126
class TestRunNotificationSettingsDialog(NotificationSettingsDialogBase):
127127

128+
title = "Test Run Notifications"
129+
128130
def _item_to_model_attrs(self, item: dict[str, Any]) -> dict[str, Any]:
129131
return {
130132
"trigger": TestRunNotificationTrigger(item["trigger"]),

0 commit comments

Comments
 (0)