Skip to content

Commit

Permalink
saving
Browse files Browse the repository at this point in the history
  • Loading branch information
KlemenSpruk committed Oct 12, 2023
1 parent bac843a commit 2a7471d
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 33 deletions.
38 changes: 34 additions & 4 deletions django_project_base/base/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,30 @@ def confirm(item):
confirm(payload)


class ProjectSettingActionRequiredEvent(BaseEvent):
def trigger_changed(self, old_state=None, new_state=None, payload=None, **kwargs):
super().trigger_changed(old_state=old_state, new_state=new_state, payload=payload, **kwargs)

def trigger(self, payload=None, **kwargs):
super().trigger(payload, **kwargs)
if not payload:
return

# if to := getattr(settings, "ADMINS", getattr(settings, "MANAGERS", [])):
# # TODO: SEND THIS AS SYSTEM MSG WHEN PR IS MERGED
# EMailNotificationWithListOfEmails(
# message=DjangoProjectBaseMessage(
# subject=gettext"Project settings action required"),
# body=f"{gettext('Action required for setting')} {payload.name} in project {payload.project.name}",
# footer="",
# content_type=DjangoProjectBaseMessage.HTML,
# ),
# recipients=to,
# project=None,
# user=None,
# ).send()


class ProjectSettingPendingResetEvent(BaseEvent):
def trigger_changed(self, old_state=None, new_state=None, payload=None, **kwargs):
super().trigger_changed(old_state=old_state, new_state=new_state, payload=payload, **kwargs)
Expand All @@ -174,11 +198,17 @@ def trigger(self, payload=None, **kwargs):
return
from django_project_base.aws.ses import AwsSes

pending_value = copy.copy(payload.python_pending_value)
payload.pending_value = None
payload.save(update_fields=["value", "pending_value"])
payload.save(update_fields=["pending_value"])

if payload.name == EMAIL_SENDER_ID_SETTING_NAME:
if payload.python_pending_value in AwsSes.list_sender_emails():
AwsSes.remove_sender_email(payload.python_pending_value)
if pending_value in AwsSes.list_sender_emails():
AwsSes.remove_sender_email(pending_value)
AwsSes.add_sender_email(payload.python_value)
if payload.python_value not in AwsSes.list_verified_sender_emails():
payload.action_required = True
payload.save(update_fields=["action_required"])
if payload.name == SMS_SENDER_ID_SETTING_NAME:
pass
payload.action_required = True
payload.save(update_fields=["action_required"])
5 changes: 5 additions & 0 deletions django_project_base/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,18 @@ def clean(self):
)

pending_value = models.CharField(max_length=320, null=True, blank=True, verbose_name=_("Pending value"))
action_required = models.BooleanField(default=False, null=True, blank=True)

def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
self.full_clean()
validator = self.value_validators[self.value_type]
self.value = validator(self.value)
if self.pending_value:
self.pending_value = validator(self.pending_value)
if self.action_required:
from django_project_base.base.event import ProjectSettingActionRequiredEvent

ProjectSettingActionRequiredEvent(user=None).trigger(payload=self)
super().save(force_insert, force_update, using, update_fields)

def delete(self, using=None, keep_parents=False):
Expand Down
47 changes: 24 additions & 23 deletions django_project_base/management/commands/list_pending_settings.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
import swapper
from django.core.management.base import BaseCommand
from django.shortcuts import get_object_or_404

from django_project_base.base.event import ProjectSettingConfirmedEvent


class Command(BaseCommand):
help = "Lists pending project settings. Example: python manage.py list_pending_settings 2"

def add_arguments(self, parser) -> None:
parser.add_argument("project-id", type=str, help="Project identifier")
help = "Lists pending project settings. Example: python manage.py list_pending_settings"

def handle(self, *args, **options):
project = get_object_or_404(swapper.load_model("django_project_base", "Project"), pk=str(options["project-id"]))
setting = get_object_or_404(
swapper.load_model("django_project_base", "ProjectSettings"),
project=project,
name=str(options["setting-name"]),
)
ProjectSettingConfirmedEvent(user=None).trigger(payload=setting)
# TODO: send email when owner is known
# SystemEMailNotification(
result = dict()
for project in swapper.load_model("django_project_base", "Project").objects.all():
for setting in (
swapper.load_model("django_project_base", "ProjectSettings")
.objects.filter(project=project, pending_value__isnull=False)
.exclude(pending_value="")
):
if project.name not in result:
result[project.name] = {}
result[project.name][setting.name] = {
"value": setting.python_value,
"pending_value": setting.python_pending_value,
}
# if to := getattr(settings, "ADMINS", getattr(settings, "MANAGERS", [])):
# TODO: SEND THIS AS SYSTEM MSG WHEN PR IS MERGED
# EMailNotificationWithListOfEmails(
# message=DjangoProjectBaseMessage(
# subject=f"{__('Project setting confirmed')}",
# body=f"{__('Setting')} {setting.name} {__('in project')} "
# f"{project.name} {__('has been confirmed and is now active.')}",
# subject=_("Pending settings report"),
# body=json.dumps(result),
# footer="",
# content_type=DjangoProjectBaseMessage.PLAIN_TEXT,
# content_type=DjangoProjectBaseMessage.HTML,
# ),
# recipients=[], # TODO: find project owner
# user=None, # TODO: find project owner
# recipients=to,
# project=None,
# user=None,
# ).send()
return "ok"
self.stdout.write(self.style.WARNING(result))
43 changes: 42 additions & 1 deletion django_project_base/rest/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import swapper
from django.conf import settings
from django.core.management import call_command
from django.db import transaction
from django.http import Http404
from django.shortcuts import get_object_or_404
Expand Down Expand Up @@ -195,12 +196,28 @@ def __init__(self, *args, is_filter: bool = False, **kwds):
),
),
)
request = self.context.get("request")
if request and (request.user.is_superuser or request.user.is_staff):
self.actions.actions.append(
TableAction(
position=TablePosition.ROW_END,
label="Confirm active",
name="confirm-setting-active",
display_style=dict(
asButton=True,
showIcon=False,
showLabel=False,
),
),
)

id = fields.AutoGeneratedField(display=DisplayMode.HIDDEN)
project = fields.PrimaryKeyRelatedField(
display=DisplayMode.SUPPRESS, queryset=swapper.load_model("django_project_base", "Project").objects.all()
)
pending_value = fields.CharField(display=DisplayMode.SUPPRESS, required=False)
pending_value = fields.CharField(
display=DisplayMode.SUPPRESS, required=False, allow_null=True, default=False, allow_blank=True
)

table_value = fields.CharField(
source="value",
Expand Down Expand Up @@ -235,6 +252,11 @@ def save(self, **kwargs):
saved = super().save(**kwargs)
return saved

def get_row_css_style(self, obj):
if obj and obj.action_required:
return "background-color:red;"
return ""

def to_representation(self, instance, row_data=None):
representation = super().to_representation(instance, row_data)
if instance and instance.pending_value:
Expand Down Expand Up @@ -390,3 +412,22 @@ def reset_pending_setting(self, request) -> Response:
if setting.pending_value:
ProjectSettingPendingResetEvent(user=request.user).trigger(payload=setting)
return Response()

@extend_schema(exclude=True)
@transaction.atomic()
@action(
detail=False,
methods=["POST"],
url_name="confirm-setting-active",
url_path="confirm-setting-active",
)
def confirm_setting_active(self, request) -> Response:
if not (request.user.is_superuser or request.user.is_staff):
raise PermissionDenied
setting = get_object_or_404(self.get_serializer_class().Meta.model, pk=self._get_pk_from_request(request))
call_command(
"confirm_setting",
setting.project.pk,
setting.name,
)
return Response()
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name="projectsettings",
name="pending_value",
field=models.CharField(
max_length=320, null=True, verbose_name="Pending value"
),
field=models.CharField(max_length=320, null=True, verbose_name="Pending value"),
),
migrations.AddField(
model_name="projectsettings",
name="action_required",
field=models.BooleanField(default=False, verbose_name="Action required", null=True, blank=True),
),
]
16 changes: 14 additions & 2 deletions vue/components/project-settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ if (selectedProjectId.value) refreshSettingsLogicAndCheckSettings();
watch(selectedProjectId, refreshSettingsLogicAndCheckSettings);
const actionResetPending = async (action:Action, payload: FormPayload) => {
console.log(action, payload);
const resetData = {};
// @ts-ignore
resetData[PROFILE_TABLE_PRIMARY_KEY_PROPERTY_NAME] = payload[PROFILE_TABLE_PRIMARY_KEY_PROPERTY_NAME];
Expand All @@ -202,10 +201,23 @@ const actionResetPending = async (action:Action, payload: FormPayload) => {
return true;
};
const actionConfirmSettingActive = async (action:Action, payload: FormPayload) => {
const activeData = {};
// @ts-ignore
active[PROFILE_TABLE_PRIMARY_KEY_PROPERTY_NAME] = payload[PROFILE_TABLE_PRIMARY_KEY_PROPERTY_NAME];
apiClient.post(
'/project-settings/reset-pending',
activeData,
).then(() => {
refreshSettingsLogic();
});
return true;
};
const { handler } = useActionHandler();
handler
.register('reset-pending', actionResetPending);
.register('reset-pending', actionResetPending).register('confirm-setting-active', actionConfirmSettingActive);
</script>

Expand Down

0 comments on commit 2a7471d

Please sign in to comment.