@@ -1,27 +1,18 @@
|
||||
import os
|
||||
import math
|
||||
from django.conf import settings
|
||||
from rest_framework import serializers
|
||||
from django.utils import timezone
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from rest_framework import serializers
|
||||
|
||||
from module_iam.models import IAmPrincipal
|
||||
from ..models import (
|
||||
PrincipalHealthData,
|
||||
Intolerance,
|
||||
Symptoms,
|
||||
PastTreatment,
|
||||
ChronicCondition,
|
||||
Medicine,
|
||||
Medication,
|
||||
Bowel,
|
||||
SymptomTypeAfterMeal,
|
||||
SymptomTypeBeforeMeal,
|
||||
MealSymptomRecord,
|
||||
FoodIngredientRecord,
|
||||
FoodRecord,
|
||||
BeverageRecord,
|
||||
MealRecord,
|
||||
)
|
||||
|
||||
from ..models import (BeverageRecord, Bowel, ChronicCondition,
|
||||
FoodIngredientRecord, FoodRecord, Intolerance,
|
||||
MealRecord, MealSymptomRecord, Medication, Medicine,
|
||||
PastTreatment, PrincipalHealthData, Symptoms,
|
||||
SymptomTypeAfterMeal, SymptomTypeBeforeMeal)
|
||||
|
||||
|
||||
class IAmPrincipalSerializer(serializers.ModelSerializer):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
@@ -25,6 +25,7 @@ urlpatterns = [
|
||||
path("meal-symptoms/<int:pk>/", views.MealSymptomAPIView.as_view()),
|
||||
|
||||
path("meal/", views.MealAPIView.as_view()),
|
||||
path("meal/date/", views.MealDateAPIView.as_view()),
|
||||
path("meal/<int:pk>/", views.MealAPIView.as_view()),
|
||||
|
||||
path("report/", views.ReportAPIView.as_view()),
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
from datetime import datetime, timedelta
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
|
||||
from django.db.models import Count, Max, Min, Prefetch
|
||||
from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
from django.db.models import Prefetch, Count, Max, Min
|
||||
from module_project import constants, date_utils
|
||||
from module_project.utils import ApiResponse
|
||||
from module_iam.models import IAmPrincipal
|
||||
from ..models import (
|
||||
PrincipalHealthData,
|
||||
Intolerance,
|
||||
Symptoms,
|
||||
PastTreatment,
|
||||
ChronicCondition,
|
||||
Medication,
|
||||
Bowel,
|
||||
MealSymptomRecord,
|
||||
MealRecord,
|
||||
)
|
||||
from .serializers import (
|
||||
IntoleranceSerializer,
|
||||
SymptomsSerializer,
|
||||
PastTreatmentSerializer,
|
||||
ChronicConditionSerializer,
|
||||
MedicationSerializer,
|
||||
BowelSerializer,
|
||||
MealSymptomRecordSerializer,
|
||||
MealRecordSerializer,
|
||||
IAmPrincipalSerializer,
|
||||
PrincipalHealthDataSerializer,
|
||||
PrincipalAndHealthSerializer,
|
||||
)
|
||||
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants, date_utils
|
||||
from module_project.service import OneSignalNotificationService
|
||||
from module_project.utils import ApiResponse
|
||||
|
||||
from ..models import (Bowel, ChronicCondition, Intolerance, MealRecord,
|
||||
MealSymptomRecord, Medication, PastTreatment,
|
||||
PrincipalHealthData, Symptoms)
|
||||
from .serializers import (BowelSerializer, ChronicConditionSerializer,
|
||||
IAmPrincipalSerializer, IntoleranceSerializer,
|
||||
MealRecordSerializer, MealSymptomRecordSerializer,
|
||||
MedicationSerializer, PastTreatmentSerializer,
|
||||
PrincipalAndHealthSerializer,
|
||||
PrincipalHealthDataSerializer, SymptomsSerializer)
|
||||
|
||||
|
||||
class ProfileAPIView(APIView):
|
||||
@@ -630,6 +617,31 @@ class MealAPIView(APIView):
|
||||
message=constants.RECORD_DELETED, status=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
|
||||
class MealDateAPIView(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = MealRecordSerializer
|
||||
model = MealRecord
|
||||
|
||||
def get(self, request):
|
||||
date = request.GET.get("date")
|
||||
|
||||
if not date:
|
||||
return ApiResponse.error(
|
||||
message=constants.FAILURE, errors="Date parameter is missing"
|
||||
)
|
||||
|
||||
try:
|
||||
# Convert the date string to a datetime object
|
||||
date_obj = datetime.strptime(date, "%Y-%m-%d").date()
|
||||
except ValueError:
|
||||
return ApiResponse.error(
|
||||
message=constants.FAILURE, errors="Invalid date format"
|
||||
)
|
||||
obj = self.model.objects.filter(date=date_obj)
|
||||
serializer = self.serializer_class(obj, many=True)
|
||||
return ApiResponse.success(message=constants.SUCCESS, data=serializer.data)
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from django import forms
|
||||
from module_project import constants
|
||||
from .models import Intolerance, Symptoms, PastTreatment, ChronicCondition
|
||||
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
|
||||
from .models import ChronicCondition, Intolerance, PastTreatment, Symptoms
|
||||
|
||||
|
||||
class IntoleranceForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
from module_iam.models import BaseModel, IAmPrincipal
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "module_activity"
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
@@ -1,35 +1,25 @@
|
||||
import logging
|
||||
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
from django.shortcuts import get_object_or_404, render, redirect
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import Count, Prefetch, Q
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from django.db.models import Q, Prefetch, Count
|
||||
from .models import (
|
||||
Intolerance,
|
||||
Symptoms,
|
||||
ChronicCondition,
|
||||
PastTreatment,
|
||||
MealRecord,
|
||||
Bowel,
|
||||
MealSymptomRecord,
|
||||
Medication,
|
||||
)
|
||||
from .forms import (
|
||||
IntoleranceForm,
|
||||
SymptomsForm,
|
||||
PastTreatmentForm,
|
||||
ChronicConditionForm,
|
||||
)
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
from module_iam.models import IAmPrincipal
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants, date_utils
|
||||
from module_project.utils import JsonResponseUtil
|
||||
from django.http import JsonResponse
|
||||
|
||||
from .forms import (ChronicConditionForm, IntoleranceForm, PastTreatmentForm,
|
||||
SymptomsForm)
|
||||
from .models import (Bowel, ChronicCondition, Intolerance, MealRecord,
|
||||
MealSymptomRecord, Medication, PastTreatment, Symptoms)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -45,7 +35,7 @@ class BaseView(generic.TemplateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["page_name"] = self.page_name
|
||||
context["principal_id"] = self.kwargs.get("principal_id")
|
||||
context["principal_id"] = get_object_or_404(IAmPrincipal, id=self.kwargs.get("principal_id"))
|
||||
return context
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from rest_framework import serializers
|
||||
from rest_framework.validators import UniqueValidator
|
||||
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
from django.contrib.auth import authenticate
|
||||
from rest_framework.validators import UniqueValidator
|
||||
|
||||
# class BasePasswordSerializer(serializers.Serializer):
|
||||
# confirm_password = serializers.CharField(write_only=True, required=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from rest_framework_simplejwt.views import TokenRefreshView
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
from django.core.exceptions import ValidationError
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
|
||||
from module_iam.models import IAmPrincipal, IAmPrincipalOtp
|
||||
from module_project import constants
|
||||
from module_project.utils import ApiResponse
|
||||
from module_iam.models import IAmPrincipal, IAmPrincipalOtp
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
from django.core.exceptions import ValidationError
|
||||
import requests
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
from datetime import datetime
|
||||
from rest_framework import status
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
from module_project import constants
|
||||
from module_project.service import SMSService, EmailService
|
||||
from module_project.utils import ApiResponse
|
||||
from .utils import AuthService, GoogleAuthService
|
||||
from django.contrib.auth import authenticate
|
||||
import requests
|
||||
from module_iam.models import AppVersion, IAmPrincipal, IAmPrincipalOtp, IAmPrincipalType, IAmPrincipalSource
|
||||
from .serializers import (
|
||||
RegistrationSerializer,
|
||||
LoginSerializer,
|
||||
OtpVerificationSerializer,
|
||||
PasswordResetSerializer,
|
||||
)
|
||||
from django.conf import settings
|
||||
from rest_framework.response import Response
|
||||
|
||||
from .utils import (
|
||||
generate_token_and_user_data,
|
||||
get_principal_by_email,
|
||||
authticate_with_otp_and_passsword,
|
||||
)
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate
|
||||
from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
|
||||
from module_iam.models import (AppVersion, IAmPrincipal, IAmPrincipalOtp,
|
||||
IAmPrincipalSource, IAmPrincipalType)
|
||||
from module_project import constants
|
||||
from module_project.service import EmailService, SMSService
|
||||
from module_project.utils import ApiResponse
|
||||
|
||||
from .serializers import (LoginSerializer, OtpVerificationSerializer,
|
||||
PasswordResetSerializer, RegistrationSerializer)
|
||||
from .utils import (AuthService, GoogleAuthService,
|
||||
authticate_with_otp_and_passsword,
|
||||
generate_token_and_user_data, get_principal_by_email)
|
||||
|
||||
|
||||
class RegistrationView(APIView):
|
||||
@@ -257,6 +253,7 @@ class GoogleSignin(APIView):
|
||||
def post(self, request):
|
||||
try:
|
||||
access_token = request.data["access_token"]
|
||||
player_id = request.data["player_id"]
|
||||
user_info = GoogleAuthService.get_user_info(access_token)
|
||||
|
||||
print(f"User Info : {user_info}")
|
||||
@@ -272,6 +269,7 @@ class GoogleSignin(APIView):
|
||||
email=user_info['email'],
|
||||
first_name=f"{user_info['given_name']} {user_info['family_name']}",
|
||||
last_login=datetime.now(),
|
||||
player_id=player_id,
|
||||
principal_type=IAmPrincipalType.get_principal_user(),
|
||||
principal_source=IAmPrincipalSource.get_principal_google()
|
||||
)
|
||||
@@ -289,6 +287,8 @@ class GoogleSignin(APIView):
|
||||
|
||||
|
||||
import jwt
|
||||
|
||||
|
||||
class AppleSignin(APIView):
|
||||
authentication_classes = []
|
||||
permission_classes = []
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from django import forms
|
||||
from django.core import validators
|
||||
from module_project import constants
|
||||
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
|
||||
|
||||
class LoginForm(forms.Form):
|
||||
email = forms.EmailField(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.urls import path
|
||||
from django.views.generic import RedirectView, TemplateView
|
||||
|
||||
from . import views
|
||||
from django.views.generic import TemplateView, RedirectView
|
||||
|
||||
app_name = "module_auth"
|
||||
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from django.db.models import Q, Prefetch
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.views import LogoutView
|
||||
from django.contrib.auth.forms import PasswordResetForm
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.views import (
|
||||
LoginView,
|
||||
PasswordResetCompleteView,
|
||||
PasswordResetConfirmView,
|
||||
PasswordResetDoneView,
|
||||
PasswordResetView,
|
||||
)
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.views import (LoginView, LogoutView,
|
||||
PasswordResetCompleteView,
|
||||
PasswordResetConfirmView,
|
||||
PasswordResetDoneView,
|
||||
PasswordResetView)
|
||||
from django.db.models import Prefetch, Q
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from .forms import LoginForm, UserForm
|
||||
from module_iam.models import IAmPrincipal, IAmPrincipalType
|
||||
from module_iam import iam_constant
|
||||
from module_activity.models import PrincipalHealthData, Intolerance, Symptoms, PastTreatment, ChronicCondition
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
|
||||
from module_activity.models import (ChronicCondition, Intolerance,
|
||||
PastTreatment, PrincipalHealthData,
|
||||
Symptoms)
|
||||
from module_iam import iam_constant
|
||||
from module_iam.models import IAmPrincipal, IAmPrincipalType
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin
|
||||
from module_project.utils import JsonResponseUtil
|
||||
|
||||
from module_project import constants
|
||||
from .forms import LoginForm, UserForm
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -169,12 +169,26 @@ class UserListJson(BaseDatatableView):
|
||||
)
|
||||
|
||||
for column in self.columns:
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)}][search][value]', None)
|
||||
# print(f"columen index pattern {}")
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)+1}][search][value]', None)
|
||||
if search_value:
|
||||
qs = qs.filter(**{f"{column}__icontains": search_value})
|
||||
|
||||
return qs
|
||||
|
||||
def ordering(self, qs):
|
||||
order = self.request.GET.get('order[0][dir]', None)
|
||||
if order:
|
||||
column_index = int(self.request.GET.get('order[0][column]', None)) - 1
|
||||
order_column = self.order_columns[column_index]
|
||||
|
||||
if order == "asc":
|
||||
qs = qs.order_by(order_column)
|
||||
elif order == "desc":
|
||||
qs = qs.order_by("-" + order_column)
|
||||
|
||||
return qs
|
||||
|
||||
class UserActionView(ActionMixin):
|
||||
model = IAmPrincipal
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from rest_framework import serializers
|
||||
from taggit.models import Tag
|
||||
|
||||
from module_cms.models import Faqs, Organization
|
||||
|
||||
|
||||
class FaqSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Faqs
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
|
||||
from module_project import constants
|
||||
from module_project.utils import ApiResponse
|
||||
from .serializers import FaqSerializer, OrganizationSerializer
|
||||
|
||||
from ..models import Faqs, Organization
|
||||
from .serializers import FaqSerializer, OrganizationSerializer
|
||||
|
||||
|
||||
class FaqListAPIView(APIView):
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core import validators
|
||||
from .models import (
|
||||
Organization,
|
||||
FaqCategory,
|
||||
Faqs,
|
||||
)
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from module_project import constants
|
||||
|
||||
from .models import FaqCategory, Faqs, Organization
|
||||
|
||||
|
||||
class OrganizationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from django.db import models
|
||||
from module_iam.models import BaseModel, IAmPrincipal
|
||||
from taggit.managers import TaggableManager
|
||||
from django_quill.fields import QuillField
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
from module_iam.models import BaseModel, IAmPrincipal
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class Organization(BaseModel):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "module_cms"
|
||||
|
||||
@@ -3,18 +3,19 @@ import logging
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_iam import iam_constant
|
||||
from .forms import AboutUsForm, TermsAndConditionForm, FaqsForm, PrivacyPolicyForm
|
||||
from .models import Faqs, Organization
|
||||
from module_project.mixins import DatatablesMixin
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
from module_project.mixins import ActionMixin
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin, DatatablesMixin
|
||||
|
||||
from .forms import (AboutUsForm, FaqsForm, PrivacyPolicyForm,
|
||||
TermsAndConditionForm)
|
||||
from .models import Faqs, Organization
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -35,8 +36,8 @@ class FaqView(LoginRequiredMixin, generic.TemplateView):
|
||||
|
||||
class FaqListJson(BaseDatatableView):
|
||||
model = Faqs
|
||||
columns = ["id", "question", "answer", "active", "deleted"]
|
||||
order_columns = ["id", "question", "answer", "active", "deleted"]
|
||||
columns = ["id", "question", "answer", "active"]
|
||||
order_columns = ["id", "question", "answer", "active"]
|
||||
|
||||
def get_initial_queryset(self):
|
||||
deleted_flag = self.request.GET.get('deleted_flag', None)
|
||||
@@ -55,11 +56,24 @@ class FaqListJson(BaseDatatableView):
|
||||
)
|
||||
|
||||
for column in self.columns:
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)}][search][value]', None)
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)+1}][search][value]', None)
|
||||
if search_value:
|
||||
qs = qs.filter(**{f"{column}__icontains": search_value})
|
||||
|
||||
return qs
|
||||
|
||||
def ordering(self, qs):
|
||||
order = self.request.GET.get('order[0][dir]', None)
|
||||
if order:
|
||||
column_index = int(self.request.GET.get('order[0][column]', None)) - 1
|
||||
order_column = self.order_columns[column_index]
|
||||
|
||||
if order == "asc":
|
||||
qs = qs.order_by(order_column)
|
||||
elif order == "desc":
|
||||
qs = qs.order_by("-" + order_column)
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
class FaqCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
|
||||
@@ -1,32 +1,30 @@
|
||||
from collections.abc import Iterable
|
||||
import datetime
|
||||
import random
|
||||
import string
|
||||
from collections.abc import Iterable
|
||||
|
||||
# from manage_wallets.models import Wallet, Transaction, TransactionStatus, TransactionType
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AbstractUser, BaseUserManager
|
||||
from django.core.cache import cache
|
||||
# from .utils import UserContext
|
||||
from django.core.validators import (MaxValueValidator, MinValueValidator,
|
||||
RegexValidator)
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.text import slugify
|
||||
|
||||
from module_project.utils import RandomGenerator
|
||||
|
||||
from .iam_constant import (PRINCIPAL_SOURCE_APP, PRINCIPAL_SOURCE_APPLE,
|
||||
PRINCIPAL_SOURCE_GOOGLE, PRINCIPAL_SOURCE_WEB,
|
||||
PRINCIPAL_TYPE_ADMIN, PRINCIPAL_TYPE_SUBADMIN,
|
||||
PRINCIPAL_TYPE_USER)
|
||||
|
||||
# from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from module_project.utils import RandomGenerator
|
||||
from .iam_constant import (
|
||||
PRINCIPAL_TYPE_USER,
|
||||
PRINCIPAL_TYPE_ADMIN,
|
||||
PRINCIPAL_TYPE_SUBADMIN,
|
||||
PRINCIPAL_SOURCE_APP,
|
||||
PRINCIPAL_SOURCE_APPLE,
|
||||
PRINCIPAL_SOURCE_GOOGLE,
|
||||
PRINCIPAL_SOURCE_WEB,
|
||||
)
|
||||
|
||||
# from .utils import UserContext
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
|
||||
|
||||
|
||||
class BaseModel(models.Model):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "module_iam"
|
||||
@@ -6,11 +7,12 @@ app_name = "module_iam"
|
||||
urlpatterns = [
|
||||
path('dashboard/', views.DashboardView.as_view(), name="dashboard"),
|
||||
|
||||
|
||||
# path('principal/', views.PrincipalListView.as_view(), name="principal_list"),
|
||||
# path('principal/add/', views.PrincipalCreateOrUpdateView.as_view(), name="principal_add"),
|
||||
path('principal/add/', views.PrincipalCreateOrUpdateView.as_view(), name="principal_add"),
|
||||
path('principal/edit/<int:pk>', views.PrincipalCreateOrUpdateView.as_view(), name="principal_edit"),
|
||||
# path('principal/delete/<int:pk>', views.PrincipalDeleteView.as_view(), name="principal_delete"),
|
||||
path('principal/archive/', views.PrincipalArchiveView.as_view(), name="principal_archive"),
|
||||
path('principal/archive/list/', views.PrincipalArchiveListJsonView.as_view(), name="principal_archive_list"),
|
||||
|
||||
path('principal/group/link/', views.PrincipalGroupLinkView.as_view(), name="principal_group_link"),
|
||||
path('principal/group/link/list/admin/', views.PrincipalGroupLinkAdminListJsonView.as_view(), name="principal_group_link_list"),
|
||||
@@ -19,16 +21,18 @@ urlpatterns = [
|
||||
path('principal/group/link/action/', views.PrincipalGroupLinkActionView.as_view(), name="principal_group_link_action"),
|
||||
|
||||
path('principal/group/', views.PrincipalGroupView.as_view(), name="principal_group"),
|
||||
path('principal/group/list', views.PrincipalGroupListJsonView.as_view(), name="principal_group_list"),
|
||||
path('principal/group/list/', views.PrincipalGroupListJsonView.as_view(), name="principal_group_list"),
|
||||
path('principal/group/add/', views.PrincipalGroupCreateOrUpdateView.as_view(), name="principal_group_add"),
|
||||
path('principal/group/edit/<int:pk>/', views.PrincipalGroupCreateOrUpdateView.as_view(), name="principal_group_edit"),
|
||||
path('principal/group/action/', views.PrincipalGroupActionView.as_view(), name="principal_group_action"),
|
||||
path('principal/group/archive/list/', views.PrincipalGroupArchiveView.as_view(), name="principal_group_archive"),
|
||||
|
||||
path('principal/role/', views.AppRoleView.as_view(), name="role"),
|
||||
path('principal/role/list/', views.AppRoleListJsonView.as_view(), name="role_list"),
|
||||
path('principal/role/add/', views.AppRoleCreateOrUpdateView.as_view(), name="role_add"),
|
||||
path('principal/role/edit/<int:pk>/', views.AppRoleCreateOrUpdateView.as_view(), name="role_edit"),
|
||||
path('principal/role/action/', views.AppRoleActionView.as_view(), name="role_action"),
|
||||
path('principal/role/archive/list/', views.AppRoleArchiveView.as_view(), name="role_archive"),
|
||||
|
||||
path("profile/", views.PrincipalProfileView.as_view(), name="profile_details"),
|
||||
path("profile/edit/", views.PrincipalProfileEditView.as_view(), name="profile_details_edit")
|
||||
|
||||
@@ -1,41 +1,29 @@
|
||||
from typing import Any
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models.base import Model as Model
|
||||
from django.db.models.query import QuerySet
|
||||
from django.views import generic
|
||||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from django.db.models.base import Model as Model
|
||||
from django.db.models.query import QuerySet
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from module_iam import iam_constant
|
||||
from module_project.mixins import DatatablesMixin
|
||||
from django.views import generic
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
from module_project.mixins import ActionMixin
|
||||
from module_project.utils import JsonResponseUtil
|
||||
from .forms import (
|
||||
CustomAuthenticationForm,
|
||||
IAmPrincipalForm,
|
||||
IAmPrincipalGroupRoleLinkForm,
|
||||
IAmPrincipalRoleAppResourceActionLinkForm,
|
||||
IAmPrincipalGroupLinkForm,
|
||||
ProfileEditForm,
|
||||
)
|
||||
from .models import (
|
||||
IAmPrincipal,
|
||||
IAmPrincipalType,
|
||||
IAmAppResourceActionLink,
|
||||
IAmPrincipalGroup,
|
||||
IAmRole,
|
||||
)
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin, DatatablesMixin
|
||||
from module_project.utils import JsonResponseUtil
|
||||
|
||||
from .forms import (CustomAuthenticationForm, IAmPrincipalForm,
|
||||
IAmPrincipalGroupLinkForm, IAmPrincipalGroupRoleLinkForm,
|
||||
IAmPrincipalRoleAppResourceActionLinkForm, ProfileEditForm)
|
||||
from .models import (IAmAppResourceActionLink, IAmPrincipal, IAmPrincipalGroup,
|
||||
IAmPrincipalType, IAmRole)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -119,6 +107,37 @@ class PrincipalCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
return render(request, template_name=self.template_name, context=context)
|
||||
|
||||
|
||||
class PrincipalArchiveListJsonView(BaseDatatableView):
|
||||
model = IAmPrincipal
|
||||
columns = ["id", "first_name", "email", "is_active"]
|
||||
order_columns = ["id", "first_name", "email", "is_active"]
|
||||
|
||||
def get_initial_queryset(self):
|
||||
deleted_flag = self.request.GET.get("deleted_flag", False)
|
||||
return self.model.objects.filter(
|
||||
deleted=deleted_flag,
|
||||
principal_type__name__in=(
|
||||
iam_constant.PRINCIPAL_TYPE_ADMIN,
|
||||
iam_constant.PRINCIPAL_TYPE_SUBADMIN,
|
||||
),
|
||||
)
|
||||
|
||||
def render_column(self, row, column):
|
||||
if column == "principal_type_name":
|
||||
return row.principal_type.name if row.principal_type else None
|
||||
return super().render_column(row, column)
|
||||
|
||||
def filter_queryset(self, qs):
|
||||
search_value = self.request.GET.get("search[value]", None)
|
||||
if search_value:
|
||||
qs = qs.filter(
|
||||
Q(id__icontains=search_value)
|
||||
| Q(first_name__icontains=search_value)
|
||||
| Q(email__icontains=search_value)
|
||||
)
|
||||
return qs
|
||||
|
||||
|
||||
class PrincipalGroupLinkView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
model = IAmPrincipal
|
||||
@@ -129,6 +148,12 @@ class PrincipalGroupLinkView(LoginRequiredMixin, generic.TemplateView):
|
||||
context["page_name"] = self.page_name
|
||||
return context
|
||||
|
||||
class PrincipalArchiveView(PrincipalGroupLinkView):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
resource = None
|
||||
action = None
|
||||
template_name = "module_iam/iam_principal_archive.html"
|
||||
|
||||
|
||||
class PrincipalGroupLinkAdminListJsonView(BaseDatatableView):
|
||||
model = IAmPrincipal
|
||||
@@ -137,8 +162,10 @@ class PrincipalGroupLinkAdminListJsonView(BaseDatatableView):
|
||||
|
||||
def get_initial_queryset(self):
|
||||
deleted_flag = self.request.GET.get("deleted_flag", False)
|
||||
return self.model.objects.filter(deleted=deleted_flag, principal_type__name=iam_constant.PRINCIPAL_TYPE_ADMIN)
|
||||
|
||||
return self.model.objects.filter(
|
||||
deleted=deleted_flag, principal_type__name=iam_constant.PRINCIPAL_TYPE_ADMIN
|
||||
)
|
||||
|
||||
def render_column(self, row, column):
|
||||
if column == "principal_type_name":
|
||||
return row.principal_type.name if row.principal_type else None
|
||||
@@ -148,7 +175,9 @@ class PrincipalGroupLinkAdminListJsonView(BaseDatatableView):
|
||||
search_value = self.request.GET.get("search[value]", None)
|
||||
if search_value:
|
||||
qs = qs.filter(
|
||||
Q(id__icontains=search_value) | Q(first_name__icontains=search_value) | Q(email__icontains=search_value)
|
||||
Q(id__icontains=search_value)
|
||||
| Q(first_name__icontains=search_value)
|
||||
| Q(email__icontains=search_value)
|
||||
)
|
||||
return qs
|
||||
|
||||
@@ -160,7 +189,10 @@ class PrincipalGroupLinkSubAdminListJsonView(BaseDatatableView):
|
||||
|
||||
def get_initial_queryset(self):
|
||||
deleted_flag = self.request.GET.get("deleted_flag", False)
|
||||
return self.model.objects.filter(deleted=deleted_flag, principal_type__name=iam_constant.PRINCIPAL_TYPE_SUBADMIN)
|
||||
return self.model.objects.filter(
|
||||
deleted=deleted_flag,
|
||||
principal_type__name=iam_constant.PRINCIPAL_TYPE_SUBADMIN,
|
||||
)
|
||||
|
||||
def render_column(self, row, column):
|
||||
if column == "principal_type_name":
|
||||
@@ -173,7 +205,9 @@ class PrincipalGroupLinkSubAdminListJsonView(BaseDatatableView):
|
||||
search_value = self.request.GET.get("search[value]", None)
|
||||
if search_value:
|
||||
qs = qs.filter(
|
||||
Q(id__icontains=search_value) | Q(first_name__icontains=search_value) | Q(email__icontains=search_value)
|
||||
Q(id__icontains=search_value)
|
||||
| Q(first_name__icontains=search_value)
|
||||
| Q(email__icontains=search_value)
|
||||
)
|
||||
return qs
|
||||
|
||||
@@ -222,24 +256,26 @@ class PrincipalGroupLinkActionView(generic.View):
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
if self.model is None:
|
||||
raise NotImplementedError("Subclasses of BaseActionView must define a 'model' attribute.")
|
||||
raise NotImplementedError(
|
||||
"Subclasses of BaseActionView must define a 'model' attribute."
|
||||
)
|
||||
|
||||
action = request.POST.get('action') # 'archive', 'active', or 'unarchive'
|
||||
ids = request.POST.getlist('ids[]') # List of IDs to perform action on
|
||||
active = request.POST.get('active')
|
||||
action = request.POST.get("action") # 'archive', 'active', or 'unarchive'
|
||||
ids = request.POST.getlist("ids[]") # List of IDs to perform action on
|
||||
active = request.POST.get("active")
|
||||
print(f"arhive action {action} and id is {ids} and active data is {active}")
|
||||
if action == 'archive':
|
||||
if action == "archive":
|
||||
# Update 'deleted' field to True for the selected users
|
||||
self.model.objects.filter(id__in=ids).update(deleted=True, is_active=False)
|
||||
message = 'Record archived successfully.'
|
||||
elif action == 'active':
|
||||
message = "Record archived successfully."
|
||||
elif action == "active":
|
||||
# Update 'active' field to True for the selected users
|
||||
self.model.objects.filter(id__in=ids).update(is_active=active.capitalize())
|
||||
message = 'Record updated successfully.'
|
||||
elif action == 'unarchive':
|
||||
message = "Record updated successfully."
|
||||
elif action == "unarchive":
|
||||
# Update 'deleted' field to False for the selected users
|
||||
self.model.objects.filter(id__in=ids).update(deleted=False)
|
||||
message = 'Record unarchived successfully.'
|
||||
message = "Record unarchived successfully."
|
||||
else:
|
||||
return JsonResponseUtil.error(message="Invalid Action")
|
||||
|
||||
@@ -266,6 +302,11 @@ class PrincipalGroupListJsonView(BaseDatatableView):
|
||||
deleted_flag = self.request.GET.get("deleted_flag", False)
|
||||
return self.model.objects.filter(deleted=deleted_flag)
|
||||
|
||||
def render_column(self, row, column):
|
||||
if column == "roles":
|
||||
return [{"name": role.name} for role in row.role.all()]
|
||||
return super().render_column(row, column)
|
||||
|
||||
def filter_queryset(self, qs):
|
||||
search_value = self.request.GET.get("search[value]", None)
|
||||
if search_value:
|
||||
@@ -274,31 +315,6 @@ class PrincipalGroupListJsonView(BaseDatatableView):
|
||||
)
|
||||
return qs
|
||||
|
||||
def generate_role_data(self, queryset):
|
||||
roles_data = []
|
||||
for obj in queryset:
|
||||
roles = [{"name": role.name} for role in obj.role.all()]
|
||||
print(f"role data is this {roles}")
|
||||
roles_data.append(
|
||||
{
|
||||
"id": obj.id,
|
||||
"name": obj.name,
|
||||
"active": str(obj.active),
|
||||
"roles": roles,
|
||||
}
|
||||
)
|
||||
return roles_data
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
roles = self.filter_queryset(self.get_initial_queryset())
|
||||
role_data = self.generate_role_data(roles)
|
||||
context = super().get_context_data(*args, **kwargs)
|
||||
context["recordsTotal"] = len(role_data)
|
||||
context["recordsFiltered"] = len(role_data)
|
||||
context["data"] = role_data
|
||||
context["result"] = "ok"
|
||||
return context
|
||||
|
||||
|
||||
class PrincipalGroupCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_GROUP
|
||||
@@ -349,6 +365,9 @@ class PrincipalGroupActionView(ActionMixin):
|
||||
model = IAmPrincipalGroup
|
||||
|
||||
|
||||
class PrincipalGroupArchiveView(PrincipalGroupView):
|
||||
template_name = "module_iam/iam_group_archive_list.html"
|
||||
|
||||
class AppRoleView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_IAM_ROLE
|
||||
model = IAmRole
|
||||
@@ -378,6 +397,22 @@ class AppRoleListJsonView(BaseDatatableView):
|
||||
.filter(deleted=deleted_flag)
|
||||
)
|
||||
|
||||
def render_column(self, row, column):
|
||||
if column == "resources":
|
||||
resources = {}
|
||||
# Loop through all the app_resource_action links for the current ro
|
||||
for link in row.app_resource_action.all():
|
||||
resource = link.app_resource.name
|
||||
action = link.app_action.name
|
||||
# If the resource is already in the dictionary, append the action to the list of actions
|
||||
if resource in resources:
|
||||
resources[resource].append(action)
|
||||
# Otherwise, add the resource to the dictionary with a list containing the action
|
||||
else:
|
||||
resources[resource] = [action]
|
||||
return resources
|
||||
return super().render_column(row, column)
|
||||
|
||||
def filter_queryset(self, qs):
|
||||
search_value = self.request.GET.get("search[value]", None)
|
||||
if search_value:
|
||||
@@ -389,36 +424,6 @@ class AppRoleListJsonView(BaseDatatableView):
|
||||
)
|
||||
return qs
|
||||
|
||||
def generate_resource_data(self, roles):
|
||||
role_data = []
|
||||
for role in roles:
|
||||
role_info = {
|
||||
"id": role.id,
|
||||
"name": role.name,
|
||||
"active": str(role.active),
|
||||
"resources": {},
|
||||
}
|
||||
|
||||
for link in role.app_resource_action.all():
|
||||
resource = link.app_resource.name
|
||||
action = link.app_action.name
|
||||
if resource in role_info["resources"]:
|
||||
role_info["resources"][resource].append(action)
|
||||
else:
|
||||
role_info["resources"][resource] = [action]
|
||||
role_data.append(role_info)
|
||||
return role_data
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
roles = self.filter_queryset(self.get_initial_queryset())
|
||||
role_data = self.generate_resource_data(roles)
|
||||
context = super().get_context_data(*args, **kwargs)
|
||||
context["recordsTotal"] = len(role_data)
|
||||
context["recordsFiltered"] = len(role_data)
|
||||
context["data"] = role_data
|
||||
context["result"] = "ok"
|
||||
return context
|
||||
|
||||
|
||||
class AppRoleCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_ROLE
|
||||
@@ -478,6 +483,10 @@ class AppRoleActionView(LoginRequiredMixin, ActionMixin):
|
||||
model = IAmRole
|
||||
|
||||
|
||||
class AppRoleArchiveView(AppRoleView):
|
||||
template_name = "module_iam/iam_role_archive.html"
|
||||
|
||||
|
||||
class PrincipalProfileView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
model = IAmPrincipal
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from django import forms
|
||||
|
||||
from .models import PushNotification
|
||||
|
||||
|
||||
class PushNotificationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = PushNotification
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from django.db import models
|
||||
|
||||
from module_iam.models import BaseModel
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class PushNotification(BaseModel):
|
||||
title = models.CharField(max_length=255)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "module_notification"
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
import itertools
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import Q
|
||||
from django.http import HttpRequest
|
||||
from django.http.response import HttpResponse as HttpResponse
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project.service import OneSignalService
|
||||
from .models import PushNotification
|
||||
from .forms import PushNotificationForm
|
||||
from module_iam import iam_constant
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
from module_project.mixins import ActionMixin
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_iam.iam_constant import PRINCIPAL_TYPE_USER
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin
|
||||
from module_project.service import OneSignalService
|
||||
from module_project.utils import JsonResponseUtil
|
||||
|
||||
from .forms import PushNotificationForm
|
||||
from .models import PushNotification
|
||||
|
||||
|
||||
# Create your views here.
|
||||
class NotificationView(LoginRequiredMixin, generic.TemplateView):
|
||||
@@ -39,7 +42,7 @@ class NotificationListJsonView(BaseDatatableView):
|
||||
order_columns = ["id", "title", "message", "active", "timestamp"]
|
||||
|
||||
def get_initial_queryset(self):
|
||||
deleted_flag = self.request.GET.get('deleted_flag', None)
|
||||
deleted_flag = self.request.GET.get("deleted_flag", None)
|
||||
|
||||
return self.model.objects.filter(deleted=deleted_flag)
|
||||
|
||||
@@ -142,10 +145,19 @@ class NotificationSendView(generic.View):
|
||||
fifteen_days_ago = datetime.now() - timedelta(days=3)
|
||||
|
||||
# Filter the IAmPrincipal objects based on the last_login field being greater than or equal to fifteen_days_ago
|
||||
player_ids = list(IAmPrincipal.objects.filter(last_login__gte=fifteen_days_ago).values_list('player_id', flat=True))
|
||||
player_ids = list(
|
||||
IAmPrincipal.objects.filter(
|
||||
principal_type__name=PRINCIPAL_TYPE_USER,
|
||||
last_login__gte=fifteen_days_ago,
|
||||
).values_list("player_id", flat=True)
|
||||
)
|
||||
# removing none from list
|
||||
player_ids = list(itertools.filterfalse(lambda x: x is None, player_ids))
|
||||
|
||||
if not obj:
|
||||
return JsonResponseUtil.error(message="No notification with such ID exists.")
|
||||
return JsonResponseUtil.error(
|
||||
message="No notification with such ID exists."
|
||||
)
|
||||
|
||||
try:
|
||||
notification = OneSignalService()
|
||||
@@ -163,4 +175,4 @@ class NotificationSendView(generic.View):
|
||||
}
|
||||
return JsonResponseUtil.error(**error_response)
|
||||
|
||||
return JsonResponseUtil.success(message="success")
|
||||
return JsonResponseUtil.success(message="success")
|
||||
|
||||
@@ -225,6 +225,7 @@ ONESIGNAL_USER_AUTH_KEY = env.str("ONESIGNAL_USER_AUTH_KEY")
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#logging
|
||||
# See https://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
|
||||
LOGGING = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
|
||||
@@ -39,8 +39,8 @@ BASE_DOMAIN = ""
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
# STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
|
||||
# STATICFILES_DIRS = [BASE_DIR.joinpath("static")]
|
||||
STATICFILES_DIRS = [BASE_DIR.joinpath("static")]
|
||||
|
||||
@@ -14,10 +14,10 @@ Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.exceptions import NotFound
|
||||
from django.http import JsonResponse
|
||||
from . import constants
|
||||
from rest_framework import status
|
||||
import string
|
||||
import random
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import stat
|
||||
import string
|
||||
|
||||
from django.http import JsonResponse
|
||||
from rest_framework import status
|
||||
from rest_framework.exceptions import NotFound
|
||||
from rest_framework.response import Response
|
||||
|
||||
from . import constants
|
||||
|
||||
|
||||
class GroupWriteRotatingFileHandler(logging.handlers.RotatingFileHandler):
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from module_support.models import ContactUs, Feedback
|
||||
|
||||
|
||||
class ContactUsSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ContactUs
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
|
||||
from module_project import constants
|
||||
from module_project.utils import ApiResponse
|
||||
from .serializers import ContactUsSerializer, FeedbackSerializer
|
||||
|
||||
from ..models import ContactUs, Feedback
|
||||
from .serializers import ContactUsSerializer, FeedbackSerializer
|
||||
|
||||
|
||||
class ContactusAPIView(APIView):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
from module_iam.models import BaseModel, IAmPrincipal
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "module_support"
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
from django.conf import settings
|
||||
from django.shortcuts import render
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_iam import iam_constant
|
||||
from module_project.service import EmailService
|
||||
from .models import ContactUs, Feedback
|
||||
from module_project.mixins import DatatablesMixin
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
from module_project.mixins import ActionMixin
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_iam.models import IAmPrincipal
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin, DatatablesMixin
|
||||
from module_project.service import EmailService
|
||||
from module_project.utils import JsonResponseUtil
|
||||
|
||||
from .models import ContactUs, Feedback
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
@@ -54,11 +55,24 @@ class ContactUsListJson(BaseDatatableView):
|
||||
)
|
||||
|
||||
for column in self.columns:
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)}][search][value]', None)
|
||||
search_value = self.request.GET.get(f'columns[{self.columns.index(column)+1}][search][value]', None)
|
||||
if search_value:
|
||||
qs = qs.filter(**{f"{column}__icontains": search_value})
|
||||
|
||||
return qs
|
||||
|
||||
def ordering(self, qs):
|
||||
order = self.request.GET.get('order[0][dir]', None)
|
||||
if order:
|
||||
column_index = int(self.request.GET.get('order[0][column]', None)) - 1
|
||||
order_column = self.order_columns[column_index]
|
||||
|
||||
if order == "asc":
|
||||
qs = qs.order_by(order_column)
|
||||
elif order == "desc":
|
||||
qs = qs.order_by("-" + order_column)
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
class ContactUsActionView(ActionMixin):
|
||||
|
||||
@@ -46,11 +46,8 @@
|
||||
</div>
|
||||
</a>
|
||||
<ul class="collapse submenu list-unstyled show" id="iam" data-bs-parent="#accordionExample">
|
||||
<li class="{% if page_name == iam_constants_context.RESOURCE_IAM_PRINCIPAL %}active{% endif %}">
|
||||
<a href=""> IAM Principal </a>
|
||||
</li>
|
||||
<li class="{% if page_name == iam_constants_context.RESOURCE_IAM_PRINCIPAL_GROUP %}active{% endif %}">
|
||||
<a href="{% url 'module_iam:principal_group_link' %}"> IAM Principal Group </a>
|
||||
<a href="{% url 'module_iam:principal_group_link' %}"> IAM Principal</a>
|
||||
</li>
|
||||
<li class="{% if page_name == iam_constants_context.RESOURCE_IAM_GROUP %}active{% endif %}">
|
||||
<a href="{% url 'module_iam:principal_group' %}"> IAM Group </a>
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
<h6 class="font-weight-bold">No of Active Users</h6>
|
||||
<h4 class="m-0 font-weight-bold">{{active_user_count}}</h4>
|
||||
</div>
|
||||
<div class="pro-icon">
|
||||
<img src="../src/assets/img/pro-icon.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,9 +25,6 @@
|
||||
<h6 class="font-weight-bold">No of Total Users</h6>
|
||||
<h4 class="m-0 font-weight-bold">{{total_user_count}}</h4>
|
||||
</div>
|
||||
<div class="pro-icon">
|
||||
<img src="../src/assets/img/pro-icon.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,16 +15,14 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>User Chronic conditions/diseases</h3>
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>User Chronic conditions/diseases - {{principal_id.id}} - {{principal_id.first_name}}</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'module_cms:faq_category_add' %}">Add
|
||||
Category</a> {% endcomment %}
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:chronic_condition_add' principal_id=principal_id%}">Add</a>
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:chronic_condition_add' principal_id=principal_id.id %}">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -84,9 +82,9 @@
|
||||
// Define DataTable instance
|
||||
var dataTableInstance
|
||||
var actionUrl = '{% url "module_activity:chronic_condition_action" %}'
|
||||
var mainUrl = '{% url "module_activity:chronic_condition_list" principal_id=principal_id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:chronic_condition_edit' principal_id=principal_id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:chronic_condition_archive' principal_id=principal_id %}"
|
||||
var mainUrl = '{% url "module_activity:chronic_condition_list" principal_id=principal_id.id %}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:chronic_condition_edit' principal_id=principal_id.id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:chronic_condition_archive' principal_id=principal_id.id %}"
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
@@ -15,16 +15,14 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>User Intolerances</h3>
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>User Intolerances - {{principal_id.id}} - {{principal_id.first_name}}</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'module_cms:faq_category_add' %}">Add
|
||||
Category</a> {% endcomment %}
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:intolerance_add' principal_id=principal_id%}">Add</a>
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:intolerance_add' principal_id=principal_id.id %}">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -84,9 +82,9 @@
|
||||
// Define DataTable instance
|
||||
var dataTableInstance
|
||||
var actionUrl = '{% url "module_activity:intolerance_action" %}'
|
||||
var mainUrl = '{% url "module_activity:intolerance_list" principal_id=principal_id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:intolerance_edit' principal_id=principal_id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:intolerance_archive' principal_id=principal_id %}"
|
||||
var mainUrl = '{% url "module_activity:intolerance_list" principal_id=principal_id.id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:intolerance_edit' principal_id=principal_id.id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:intolerance_archive' principal_id=principal_id.id %}"
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
tableName = $('#table')
|
||||
|
||||
@@ -15,16 +15,14 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>User Past Treatment</h3>
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>User Past Treatment - {{principal_id.id}} - {{principal_id.first_name}}</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'module_cms:faq_category_add' %}">Add
|
||||
Category</a> {% endcomment %}
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:past_treatment_add' principal_id=principal_id%}">Add</a>
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:past_treatment_add' principal_id=principal_id.id%}">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -84,9 +82,9 @@
|
||||
// Define DataTable instance
|
||||
var dataTableInstance
|
||||
var actionUrl = '{% url "module_activity:past_treatment_action" %}'
|
||||
var mainUrl = '{% url "module_activity:past_treatment_list" principal_id=principal_id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:past_treatment_edit' principal_id=principal_id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:past_treatment_archive' principal_id=principal_id %}"
|
||||
var mainUrl = '{% url "module_activity:past_treatment_list" principal_id=principal_id.id %}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:past_treatment_edit' principal_id=principal_id.id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:past_treatment_archive' principal_id=principal_id.id %}"
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
@@ -15,16 +15,14 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>User Symptoms</h3>
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>User Symptoms - {{principal_id.id}} - {{principal_id.first_name}}</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'module_cms:faq_category_add' %}">Add
|
||||
Category</a> {% endcomment %}
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:symptoms_add' principal_id=principal_id%}">Add</a>
|
||||
<a class="btn btn-primary mb-2 me-4" href="{% url 'module_activity:symptoms_add' principal_id=principal_id.id %}">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -84,9 +82,9 @@
|
||||
// Define DataTable instance
|
||||
var dataTableInstance
|
||||
var actionUrl = '{% url "module_activity:symptoms_action" %}'
|
||||
var mainUrl = '{% url "module_activity:symptoms_list" principal_id=principal_id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:symptoms_edit' principal_id=principal_id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:symptoms_archive' principal_id=principal_id %}"
|
||||
var mainUrl = '{% url "module_activity:symptoms_list" principal_id=principal_id.id%}?deleted_flag=False';
|
||||
var editUrl = "{% url 'module_activity:symptoms_edit' principal_id=principal_id.id pk=0 %}"
|
||||
var viewArchiveUrl = "{% url 'module_activity:symptoms_archive' principal_id=principal_id.id %}"
|
||||
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a class="d-flex align-items-center pl-2"onclick="history.back()">
|
||||
<img class="" src="{% static 'src/assets/img/left-arrow.svg' %}" style="height: 20px;">
|
||||
<h3 class="m-2">{{operation}} User</h3>
|
||||
<a href="{% url 'module_auth:users'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} User</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>User Details</h3>
|
||||
<a href="{% url 'module_auth:users'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>User Details</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a class="d-flex align-items-center pl-2"onclick="history.back()">
|
||||
<img class="" src="{% static 'src/assets/img/left-arrow.svg' %}" style="height: 20px;">
|
||||
<h3 class="card-title m-2">Users Archive List</h3>
|
||||
<a href="{% url 'module_auth:users'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Users Archive List</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
aria-controls="style-3" aria-sort="ascending" style="width: 50.2656px;">
|
||||
#</th>
|
||||
<th class="sorting_asc text-center" tabindex="0" aria-controls="style-3"
|
||||
aria-sort="ascending" style="width: 50.2656px;">#</th>
|
||||
aria-sort="ascending" style="width: 50.2656px;">id</th>
|
||||
<th class="sorting text-center" tabindex="1" aria-controls="style-3"
|
||||
colspan="1" style="width: 44.2344px;">Name</th>
|
||||
<th class="sorting text-center" tabindex="2" aria-controls="style-3"
|
||||
@@ -134,6 +134,7 @@ function initializeDataTable(tableName, mainUrl) {
|
||||
{ data: null, className: "text-center", render: renderActions }
|
||||
],
|
||||
debug: true,
|
||||
order: [[1, 'desc']],
|
||||
columnDefs: [
|
||||
{ targets: [1, 2, 3, 4, 5], searchable: true, orderable: true },
|
||||
{ targets: [0, -1], searchable: false, orderable: false }
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} Faq</h3>
|
||||
<a href="{% url 'module_cms:faq'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Faq</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
@@ -14,14 +14,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} Privacy Policy</h3>
|
||||
<a href="{% url 'module_cms:privacy_policy'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Privacy Policy</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
@@ -14,14 +14,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} Terms and Condition</h3>
|
||||
<a href="{% url 'module_cms:terms_and_condition'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Terms and Condition</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
@@ -95,7 +95,7 @@ var dataTableInstance;
|
||||
var mainUrl = "{% url 'module_iam:principal_group_list' %}?deleted_flag=False"
|
||||
var editUrl = "{% url 'module_iam:principal_group_edit' pk=0 %}"
|
||||
var actionUrl = "{% url 'module_iam:principal_group_action' %}"
|
||||
|
||||
var viewArchiveUrl = "{% url 'module_iam:principal_group_archive' %}"
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -152,7 +152,7 @@ function initializeDataTable(tableName, mainUrl) {
|
||||
className: "btn btn-dark ",
|
||||
action: function () {
|
||||
// Add your action here, e.g., redirect to archive page
|
||||
window.location.href = '/archive';
|
||||
window.location.href = viewArchiveUrl;
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -13,14 +13,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} Principal Group</h3>
|
||||
<a href="{% url 'module_iam:principal_group'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Principal Group</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
248
templates/module_iam/iam_group_archive_list.html
Normal file
248
templates/module_iam/iam_group_archive_list.html
Normal file
@@ -0,0 +1,248 @@
|
||||
{% extends 'base_structure/layout/base_template.html' %}
|
||||
{% load static %}
|
||||
{% block stylesheet %}
|
||||
<!-- include required css cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_css.html" %}
|
||||
{% include "cdn_through_html/switches_cdn_css.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_css.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="row layout-top-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a href="{% url 'module_iam:principal_group'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Principal Group Archive List</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="statbox widget box box-shadow">
|
||||
<div class="widget-content widget-content-area">
|
||||
<div id="table_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table style-3 dt-table-hover dataTable" role="grid"
|
||||
aria-describedby="style-3_info">
|
||||
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th class="checkbox-column text-center sorting_asc" tabindex="0"
|
||||
aria-controls="style-3" rowspan="1" colspan="1" aria-sort="ascending"
|
||||
aria-label=" Record Id : activate to sort column descending"
|
||||
style="width: 69.2656px;"> Id </th>
|
||||
<th class="checkbox-column text-center sorting_asc" tabindex="0"
|
||||
aria-controls="style-3" rowspan="1" colspan="1" aria-sort="ascending"
|
||||
aria-label=" Record Id : activate to sort column descending"
|
||||
style="width: 69.2656px;"> Id </th>
|
||||
<th class="text-center sorting" tabindex="0" aria-controls="style-3" rowspan="1"
|
||||
colspan="1" aria-label="Image: activate to sort column ascending"
|
||||
style="width: 44.2344px;">Group Name</th>
|
||||
<th class="text-center sorting" tabindex="0" aria-controls="style-3" rowspan="1"
|
||||
colspan="1" aria-label="Image: activate to sort column ascending"
|
||||
style="width: 44.2344px;">Role</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block javascript %}
|
||||
<!-- include required js cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_js.html" %}
|
||||
{% include "cdn_through_html/datatable_button_cdn_js.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_js.html" %}
|
||||
|
||||
<script>
|
||||
|
||||
// Define DataTable instance
|
||||
var dataTableInstance;
|
||||
var mainUrl = "{% url 'module_iam:principal_group_list' %}?deleted_flag=True"
|
||||
var actionUrl = "{% url 'module_iam:principal_group_action' %}"
|
||||
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
tableName = $('#table');
|
||||
dataTableInstance = initializeDataTable(tableName, mainUrl);
|
||||
viewClickEvent(dataTableInstance, viewUrl);
|
||||
editClickEvent();
|
||||
activeSwitchEventListener()
|
||||
});
|
||||
|
||||
// Function to initialize DataTable
|
||||
function initializeDataTable(tableName, mainUrl) {
|
||||
return tableName.DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
ajax: {
|
||||
url: mainUrl,
|
||||
type: "GET",
|
||||
},
|
||||
columns: [
|
||||
{ data: null, className: "text-center", render: renderCheckbox },
|
||||
{ data: "id", className: "text-center" },
|
||||
{ data: "name" },
|
||||
{ data: "roles", render: renderRole},
|
||||
],
|
||||
debug: true,
|
||||
columnDefs: [
|
||||
{ targets: [1, 2], searchable: true, orderable: true },
|
||||
],
|
||||
dom: "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'Bf>>>" +
|
||||
"<'table-responsive'tr>" +
|
||||
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
|
||||
buttons: [
|
||||
{
|
||||
text: 'UnArchive',
|
||||
className: "btn btn-dark buttons-unarchive",
|
||||
action: unArchiveAction,
|
||||
init: function(api, node, config){
|
||||
$(node).hide();
|
||||
}
|
||||
}
|
||||
],
|
||||
oLanguage: {
|
||||
oPaginate: { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
|
||||
sInfo: "Showing page _PAGE_ of _PAGES_",
|
||||
sSearch: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
|
||||
sSearchPlaceholder: "Search...",
|
||||
sLengthMenu: " _MENU_",
|
||||
},
|
||||
stripeClasses: [],
|
||||
lengthMenu: [5, 10, 20, 50],
|
||||
pageLength: 10,
|
||||
initComplete: initCompleteCallback
|
||||
});
|
||||
}
|
||||
|
||||
function renderRole(data, type, row) {
|
||||
if (type === 'display' && row.roles) {
|
||||
let html = '<ul>';
|
||||
for (const [index, role] of Object.entries(row.roles)) {
|
||||
html += `<li class="mb-1"><span class="badge badge-primary">${role.name}</span></li>`;
|
||||
}
|
||||
html += '</ul>';
|
||||
return html;
|
||||
} else if (type === 'display' && !row.roles) {
|
||||
return '<span class="badge badge-danger">No Permission assigned</span>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Function to reload the DataTable
|
||||
function reloadDataTable() {
|
||||
dataTableInstance.ajax.reload();
|
||||
}
|
||||
|
||||
// Render checkbox
|
||||
function renderCheckbox(data, type, row) {
|
||||
var checkboxHTML = '<div class="form-check form-check-danger">';
|
||||
checkboxHTML += '<input class="form-check-input archive-checkbox" type="checkbox" value="' + row.id + '" id="checkbox-' + row.id + '">';
|
||||
checkboxHTML += '</div>';
|
||||
return checkboxHTML;
|
||||
}
|
||||
|
||||
|
||||
// Callback function for DataTable initialization complete event
|
||||
function initCompleteCallback() {
|
||||
var api = this.api();
|
||||
|
||||
// Add event listener for checkbox change
|
||||
$('body').on('change', 'input[type="checkbox"]', function () {
|
||||
var checkedCount = $('tbody input.archive-checkbox:checked').length;
|
||||
var archiveButton = $('.buttons-unarchive');
|
||||
archiveButton.toggle(checkedCount > 0);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Function to handle archive action
|
||||
function unArchiveAction() {
|
||||
// Get all the checked checkboxes
|
||||
var checkedCheckboxes = $('.archive-checkbox:checked');
|
||||
// If no checkboxes are checked, show an error message
|
||||
if (checkedCheckboxes.length === 0) {
|
||||
Swal.fire({
|
||||
title: 'No users selected',
|
||||
text: 'Please select at least one user to archive.',
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Get the IDs of the checked checkboxes
|
||||
var ids = checkedCheckboxes.map(function() {
|
||||
return $(this).val();
|
||||
}).get();
|
||||
// Perform archive action with the collected user IDs
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: 'Once archived, you will recover it from archive list!',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Yes, archive it!'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// Perform archive action
|
||||
$.ajax({
|
||||
url: actionUrl, // Replace with your archive endpoint
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: "unarchive",
|
||||
ids: ids,
|
||||
csrfmiddlewaretoken: '{{csrf_token}}'
|
||||
},
|
||||
success: function(response) {
|
||||
// Show success message
|
||||
Swal.fire({
|
||||
title: 'Done!',
|
||||
text: response.msg,
|
||||
icon: 'success',
|
||||
showConfirmButton: true
|
||||
});
|
||||
// Optionally, you can reload the DataTable after successful archive
|
||||
reloadDataTable();
|
||||
},
|
||||
error: function(response) {
|
||||
// Show error message
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -10,14 +10,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} Principal</h3>
|
||||
<a href="{% url 'module_iam:principal_group_link'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Principal</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
244
templates/module_iam/iam_principal_archive.html
Normal file
244
templates/module_iam/iam_principal_archive.html
Normal file
@@ -0,0 +1,244 @@
|
||||
{% extends 'base_structure/layout/base_template.html' %}
|
||||
{% load static %}
|
||||
{% block stylesheet %}
|
||||
<!-- include required css cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_css.html" %}
|
||||
{% include "cdn_through_html/switches_cdn_css.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_css.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="row layout-top-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a href="{% url 'module_iam:principal_group_link'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Principal Archive List</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="statbox widget box box-shadow">
|
||||
<div class="widget-content widget-content-area">
|
||||
<div id="table_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table style-3 dt-table-hover dataTable" role="grid"
|
||||
aria-describedby="style-3_info">
|
||||
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th class="checkbox-column sorting_asc text-center" tabindex="0"
|
||||
aria-controls="style-3" aria-sort="ascending" style="width: 50.2656px;">
|
||||
#</th>
|
||||
<th class="sorting_asc text-center" tabindex="0" aria-controls="style-3"
|
||||
aria-sort="ascending" style="width: 50.2656px;">id</th>
|
||||
<th class="sorting text-center" tabindex="1" aria-controls="style-3"
|
||||
colspan="1" style="width: 44.2344px;">Name</th>
|
||||
<th class="sorting text-center" tabindex="2" aria-controls="style-3"
|
||||
colspan="1" style="width: 44.2344px;">Email</th>
|
||||
<th class="sorting text-center" tabindex="3" aria-controls="style-3"
|
||||
style="width: 79.7969px;">Principal Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block javascript %}
|
||||
<!-- include required js cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_js.html" %}
|
||||
{% include "cdn_through_html/datatable_button_cdn_js.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_js.html" %}
|
||||
|
||||
<script>
|
||||
|
||||
// Define DataTable instance
|
||||
var dataTableInstance;
|
||||
var mainUrl = "{% url 'module_iam:principal_archive_list' %}?deleted_flag=True"
|
||||
var actionUrl = "{% url 'module_iam:principal_group_link_action' %}"
|
||||
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
tableName = $('#table');
|
||||
dataTableInstance = initializeDataTable(tableName, mainUrl);
|
||||
viewClickEvent(dataTableInstance, viewUrl);
|
||||
editClickEvent();
|
||||
activeSwitchEventListener()
|
||||
});
|
||||
|
||||
// Function to initialize DataTable
|
||||
function initializeDataTable(tableName, mainUrl) {
|
||||
return tableName.DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
ajax: {
|
||||
url: mainUrl,
|
||||
type: "GET",
|
||||
},
|
||||
columns: [
|
||||
{ data: null, className: "text-center", render: renderCheckbox },
|
||||
{ data: "id", className: "text-center" },
|
||||
{ data: "first_name", className: "text-center" },
|
||||
{ data: "email", className: "text-center" },
|
||||
{ data: "principal_type_name", className: "text-center" },
|
||||
],
|
||||
debug: true,
|
||||
columnDefs: [
|
||||
{ targets: [1, 2, 3, 4], searchable: true, orderable: true },
|
||||
],
|
||||
dom: "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'Bf>>>" +
|
||||
"<'table-responsive'tr>" +
|
||||
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
|
||||
buttons: [
|
||||
{
|
||||
text: 'UnArchive',
|
||||
className: "btn btn-dark buttons-unarchive",
|
||||
action: unArchiveAction,
|
||||
init: function(api, node, config){
|
||||
$(node).hide();
|
||||
}
|
||||
}
|
||||
],
|
||||
oLanguage: {
|
||||
oPaginate: { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
|
||||
sInfo: "Showing page _PAGE_ of _PAGES_",
|
||||
sSearch: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
|
||||
sSearchPlaceholder: "Search...",
|
||||
sLengthMenu: " _MENU_",
|
||||
},
|
||||
stripeClasses: [],
|
||||
lengthMenu: [5, 10, 20, 50],
|
||||
pageLength: 10,
|
||||
initComplete: initCompleteCallback
|
||||
});
|
||||
}
|
||||
|
||||
// Function to reload the DataTable
|
||||
function reloadDataTable() {
|
||||
dataTableInstance.ajax.reload();
|
||||
}
|
||||
|
||||
// Render checkbox
|
||||
function renderCheckbox(data, type, row) {
|
||||
var checkboxHTML = '<div class="form-check form-check-danger">';
|
||||
checkboxHTML += '<input class="form-check-input archive-checkbox" type="checkbox" value="' + row.id + '" id="checkbox-' + row.id + '">';
|
||||
checkboxHTML += '</div>';
|
||||
return checkboxHTML;
|
||||
}
|
||||
|
||||
|
||||
// Callback function for DataTable initialization complete event
|
||||
function initCompleteCallback() {
|
||||
var api = this.api();
|
||||
|
||||
// Add individual search inputs to the first row of the thead section
|
||||
$('thead#filterboxrow th').each(function (index) {
|
||||
var title = $(this).text();
|
||||
var input = $('<input type="text" class="form-control" placeholder="Search ' + title + '"/>')
|
||||
.on('keyup change', function () {
|
||||
if (api.column(index).search() !== this.value) {
|
||||
api.column(index).search(this.value).draw();
|
||||
}
|
||||
});
|
||||
|
||||
$(this).empty().append(input);
|
||||
});
|
||||
|
||||
// Add event listener for checkbox change
|
||||
$('body').on('change', 'input[type="checkbox"]', function () {
|
||||
var checkedCount = $('#table tbody input.archive-checkbox:checked').length;
|
||||
var archiveButton = $('.buttons-unarchive');
|
||||
archiveButton.toggle(checkedCount > 0);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Function to handle archive action
|
||||
function unArchiveAction() {
|
||||
// Get all the checked checkboxes
|
||||
var checkedCheckboxes = $('.archive-checkbox:checked');
|
||||
// If no checkboxes are checked, show an error message
|
||||
if (checkedCheckboxes.length === 0) {
|
||||
Swal.fire({
|
||||
title: 'No users selected',
|
||||
text: 'Please select at least one user to archive.',
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Get the IDs of the checked checkboxes
|
||||
var ids = checkedCheckboxes.map(function() {
|
||||
return $(this).val();
|
||||
}).get();
|
||||
// Perform archive action with the collected user IDs
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: 'Once archived, you will recover it from archive list!',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Yes, archive it!'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// Perform archive action
|
||||
$.ajax({
|
||||
url: actionUrl, // Replace with your archive endpoint
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: "unarchive",
|
||||
ids: ids,
|
||||
csrfmiddlewaretoken: '{{csrf_token}}'
|
||||
},
|
||||
success: function(response) {
|
||||
// Show success message
|
||||
Swal.fire({
|
||||
title: 'Done!',
|
||||
text: response.msg,
|
||||
icon: 'success',
|
||||
showConfirmButton: true
|
||||
});
|
||||
// Optionally, you can reload the DataTable after successful archive
|
||||
reloadDataTable();
|
||||
},
|
||||
error: function(response) {
|
||||
// Show error message
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -21,11 +21,7 @@
|
||||
<h3>Manage Principal</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'manage_cms:faq_category_add' %}">Add Category</a> {% endcomment %}
|
||||
<a class="btn btn-success mb-2 me-4" href="{% url 'module_iam:principal_add' %}">Add Principal</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -178,9 +174,6 @@
|
||||
|
||||
// Define DataTable instance
|
||||
var dataTableInstance;
|
||||
var adminMainUrl = "{% url 'module_iam:principal_group_link_list' %}?deleted_flag=False"
|
||||
var editUrl = "{% url 'module_iam:principal_edit' pk=0 %}"
|
||||
var actionUrl = "{% url 'module_iam:principal_group_link_action' %}"
|
||||
|
||||
|
||||
// Entry point
|
||||
@@ -190,14 +183,16 @@ $(document).ready(function() {
|
||||
tableId: '#table',
|
||||
MainUrl: "{% url 'module_iam:principal_group_link_list' %}?deleted_flag=False",
|
||||
actionUrl: "{% url 'module_iam:principal_group_link_action' %}",
|
||||
editUrl: "{% url 'module_iam:principal_edit' pk=0 %}"
|
||||
editUrl: "{% url 'module_iam:principal_edit' pk=0 %}",
|
||||
viewArchiveUrl: "{% url 'module_iam:principal_archive' %}"
|
||||
};
|
||||
|
||||
const table2Settings = {
|
||||
tableId: '#table2',
|
||||
MainUrl: "{% url 'module_iam:principal_group_link_list_sub' %}?deleted_flag=False",
|
||||
actionUrl: "{% url 'module_iam:principal_group_link_action' %}",
|
||||
editUrl: "{% url 'module_iam:principal_group_link_edit' pk=0 %}"
|
||||
editUrl: "{% url 'module_iam:principal_group_link_edit' pk=0 %}",
|
||||
viewArchiveUrl: "{% url 'module_iam:principal_archive' %}"
|
||||
};
|
||||
|
||||
dataTableInstance = initializeDataTable(table1Settings);
|
||||
@@ -272,7 +267,7 @@ function initializeDataTable(tableSettings) {
|
||||
className: "btn btn-dark ",
|
||||
action: function () {
|
||||
// Add your action here, e.g., redirect to archive page
|
||||
window.location.href = '/archive';
|
||||
window.location.href = tableSettings.viewArchiveUrl;
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -354,7 +349,7 @@ function initialize2DataTable(tableSettings) {
|
||||
className: "btn btn-dark ",
|
||||
action: function () {
|
||||
// Add your action here, e.g., redirect to archive page
|
||||
window.location.href = '/archive';
|
||||
window.location.href = tableSettings.viewArchiveUrl;
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -95,7 +95,7 @@ var dataTableInstance;
|
||||
var mainUrl = "{% url 'module_iam:role_list' %}?deleted_flag=False"
|
||||
var editUrl = "{% url 'module_iam:role_edit' pk=0 %}"
|
||||
var actionUrl = "{% url 'module_iam:role_action' %}"
|
||||
|
||||
var viewArchiveUrl = "{% url 'module_iam:role_archive' %}"
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -118,7 +118,7 @@ function initializeDataTable(tableName, mainUrl) {
|
||||
{ data: null, className: "text-center", render: renderCheckbox },
|
||||
{ data: "id", className: "text-center" },
|
||||
{ data: "name" },
|
||||
{ data: "resource", render: renderResources },
|
||||
{ data: "resources", render: renderResources },
|
||||
{ data: "active", className: "text-center", render: renderSwitch },
|
||||
{ data: null, className: "text-center", render: renderActions }
|
||||
],
|
||||
@@ -135,7 +135,7 @@ function initializeDataTable(tableName, mainUrl) {
|
||||
orderable: false
|
||||
},
|
||||
{
|
||||
targets: [0,-1], // Targeting the last column (action column)
|
||||
targets: [0], // Targeting the last column (action column)
|
||||
searchable: false,
|
||||
orderable: false
|
||||
},
|
||||
@@ -157,7 +157,7 @@ function initializeDataTable(tableName, mainUrl) {
|
||||
className: "btn btn-dark ",
|
||||
action: function () {
|
||||
// Add your action here, e.g., redirect to archive page
|
||||
window.location.href = '/archive';
|
||||
window.location.href = viewArchiveUrl;
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -13,14 +13,12 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>Add Role and Assgin Permission</h3>
|
||||
<a href="{% url 'module_iam:role'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Add Role and Assgin Permission</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
|
||||
252
templates/module_iam/iam_role_archive.html
Normal file
252
templates/module_iam/iam_role_archive.html
Normal file
@@ -0,0 +1,252 @@
|
||||
{% extends 'base_structure/layout/base_template.html' %}
|
||||
{% load static %}
|
||||
{% block stylesheet %}
|
||||
<!-- include required css cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_css.html" %}
|
||||
{% include "cdn_through_html/switches_cdn_css.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_css.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="row layout-top-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a href="{% url 'module_iam:role'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Role Archive List</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row layout-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="statbox widget box box-shadow">
|
||||
<div class="widget-content widget-content-area">
|
||||
<div id="table_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table style-3 dt-table-hover dataTable" role="grid"
|
||||
aria-describedby="style-3_info">
|
||||
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th class="checkbox-column text-center sorting_asc" tabindex="0"
|
||||
aria-controls="style-3" rowspan="1" colspan="1" aria-sort="ascending"
|
||||
aria-label=" Record Id : activate to sort column descending"
|
||||
style="width: 69.2656px;"> Id </th>
|
||||
<th class="checkbox-column text-center sorting_asc" tabindex="0"
|
||||
aria-controls="style-3" rowspan="1" colspan="1" aria-sort="ascending"
|
||||
aria-label=" Record Id : activate to sort column descending"
|
||||
style="width: 69.2656px;"> Id </th>
|
||||
<th class="text-center sorting" tabindex="0" aria-controls="style-3" rowspan="1"
|
||||
colspan="1" aria-label="Image: activate to sort column ascending"
|
||||
style="width: 44.2344px;">Role Name</th>
|
||||
<th class="sorting" tabindex="0" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
aria-label="First Name: activate to sort column ascending"
|
||||
style="width: 79.7969px;">Permission</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% block javascript %}
|
||||
<!-- include required js cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_js.html" %}
|
||||
{% include "cdn_through_html/datatable_button_cdn_js.html" %}
|
||||
{% include "cdn_through_html/sweetalert2_cdn_js.html" %}
|
||||
|
||||
<script>
|
||||
|
||||
// Define DataTable instance
|
||||
var dataTableInstance;
|
||||
var mainUrl = "{% url 'module_iam:role_list' %}?deleted_flag=True"
|
||||
var actionUrl = "{% url 'module_iam:role_action' %}"
|
||||
|
||||
// Entry point
|
||||
$(document).ready(function() {
|
||||
|
||||
tableName = $('#table');
|
||||
dataTableInstance = initializeDataTable(tableName, mainUrl);
|
||||
viewClickEvent(dataTableInstance, viewUrl);
|
||||
editClickEvent();
|
||||
activeSwitchEventListener()
|
||||
});
|
||||
|
||||
// Function to initialize DataTable
|
||||
function initializeDataTable(tableName, mainUrl) {
|
||||
return tableName.DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
ajax: {
|
||||
url: mainUrl,
|
||||
type: "GET",
|
||||
},
|
||||
columns: [
|
||||
{ data: null, className: "text-center", render: renderCheckbox },
|
||||
{ data: "id", className: "text-center" },
|
||||
{ data: "name" },
|
||||
{ data: "resource", render: renderResources },
|
||||
],
|
||||
debug: true,
|
||||
columnDefs: [
|
||||
{ targets: [1, 2], searchable: true, orderable: true },
|
||||
],
|
||||
dom: "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'Bf>>>" +
|
||||
"<'table-responsive'tr>" +
|
||||
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
|
||||
buttons: [
|
||||
{
|
||||
text: 'UnArchive',
|
||||
className: "btn btn-dark buttons-unarchive",
|
||||
action: unArchiveAction,
|
||||
init: function(api, node, config){
|
||||
$(node).hide();
|
||||
}
|
||||
}
|
||||
],
|
||||
oLanguage: {
|
||||
oPaginate: { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
|
||||
sInfo: "Showing page _PAGE_ of _PAGES_",
|
||||
sSearch: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
|
||||
sSearchPlaceholder: "Search...",
|
||||
sLengthMenu: " _MENU_",
|
||||
},
|
||||
stripeClasses: [],
|
||||
lengthMenu: [5, 10, 20, 50],
|
||||
pageLength: 10,
|
||||
initComplete: initCompleteCallback
|
||||
});
|
||||
}
|
||||
|
||||
function renderResources(data, type, row) {
|
||||
if (type === 'display' && row.resources) {
|
||||
let html = '<ul>';
|
||||
for (const [resource, actions] of Object.entries(row.resources)) {
|
||||
html += `<li class="mb-1"><span class="badge badge-primary">${resource}</span>`;
|
||||
for (const action of actions) {
|
||||
html += `<span class="badge badge-secondary">${action}</span>`;
|
||||
}
|
||||
html += '</li>';
|
||||
}
|
||||
html += '</ul>';
|
||||
return html;
|
||||
} else if (type === 'display' && !row.resources) {
|
||||
return '<span class="badge badge-danger">No Permission assigned</span>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Function to reload the DataTable
|
||||
function reloadDataTable() {
|
||||
dataTableInstance.ajax.reload();
|
||||
}
|
||||
|
||||
// Render checkbox
|
||||
function renderCheckbox(data, type, row) {
|
||||
var checkboxHTML = '<div class="form-check form-check-danger">';
|
||||
checkboxHTML += '<input class="form-check-input archive-checkbox" type="checkbox" value="' + row.id + '" id="checkbox-' + row.id + '">';
|
||||
checkboxHTML += '</div>';
|
||||
return checkboxHTML;
|
||||
}
|
||||
|
||||
|
||||
// Callback function for DataTable initialization complete event
|
||||
function initCompleteCallback() {
|
||||
var api = this.api();
|
||||
|
||||
// Add event listener for checkbox change
|
||||
$('body').on('change', 'input[type="checkbox"]', function () {
|
||||
var checkedCount = $('tbody input.archive-checkbox:checked').length;
|
||||
var archiveButton = $('.buttons-unarchive');
|
||||
archiveButton.toggle(checkedCount > 0);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Function to handle archive action
|
||||
function unArchiveAction() {
|
||||
// Get all the checked checkboxes
|
||||
var checkedCheckboxes = $('.archive-checkbox:checked');
|
||||
// If no checkboxes are checked, show an error message
|
||||
if (checkedCheckboxes.length === 0) {
|
||||
Swal.fire({
|
||||
title: 'No users selected',
|
||||
text: 'Please select at least one user to archive.',
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Get the IDs of the checked checkboxes
|
||||
var ids = checkedCheckboxes.map(function() {
|
||||
return $(this).val();
|
||||
}).get();
|
||||
// Perform archive action with the collected user IDs
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: 'Once archived, you will recover it from archive list!',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'Yes, archive it!'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// Perform archive action
|
||||
$.ajax({
|
||||
url: actionUrl, // Replace with your archive endpoint
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: "unarchive",
|
||||
ids: ids,
|
||||
csrfmiddlewaretoken: '{{csrf_token}}'
|
||||
},
|
||||
success: function(response) {
|
||||
// Show success message
|
||||
Swal.fire({
|
||||
title: 'Done!',
|
||||
text: response.msg,
|
||||
icon: 'success',
|
||||
showConfirmButton: true
|
||||
});
|
||||
// Optionally, you can reload the DataTable after successful archive
|
||||
reloadDataTable();
|
||||
},
|
||||
error: function(response) {
|
||||
// Show error message
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: response.message,
|
||||
icon: 'error',
|
||||
showConfirmButton: true
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -10,16 +10,13 @@
|
||||
<div class="row layout-top-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>Profile</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
{% comment %} <a class="btn btn-primary mb-2 me-4" href="{% url 'accounts:role_add' %}">Add Role</a> {% endcomment %}
|
||||
</div>
|
||||
<div class="col">
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Profile</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row layout-spacing">
|
||||
|
||||
@@ -12,14 +12,11 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>Profile</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button>
|
||||
{% comment %} <a class="btn btn-primary mb-2 me-4" href="{% url 'accounts:role_add' %}">Add Role</a> {%endcomment %}
|
||||
<a onclick="history.back()" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Edit Profile</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<a class="d-flex align-items-center pl-2"onclick="history.back()">
|
||||
<img class="" src="{% static 'src/assets/img/left-arrow.svg' %}" style="height: 20px;">
|
||||
<h3 class="m-2">{{operation}} Notification</h3>
|
||||
<a href="{% url 'module_notification:notification'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>{{operation}} Notification</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,15 +16,11 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>Archive Contact Us</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
Back
|
||||
</button> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-success mb-2 me-4" href="{% url 'module_cms:faq_category_add' %}">Add Category</a> {% endcomment %}
|
||||
{% comment %} <a class="btn btn-primary mb-2 me-4" href="{% url 'module_cms:faq_add' %}">Add FAQ</a> {% endcomment %}
|
||||
<a href="{% url 'module_cms:privacy_policy'%}" style="height: fit-content;width: fit-content;display: inline-block;">
|
||||
<h3 class="card-title m-2 d-flex align-items-center gap-2" style="width: fit-content;"><span class="fw-bold material-symbols-outlined">
|
||||
arrow_back
|
||||
</span><span>Archive Contact Us</span></h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user