diff --git a/src/servala/frontend/templates/frontend/organization_selection.html b/src/servala/frontend/templates/frontend/organization_selection.html deleted file mode 100644 index 04db6ec..0000000 --- a/src/servala/frontend/templates/frontend/organization_selection.html +++ /dev/null @@ -1,111 +0,0 @@ -{% extends "frontend/base.html" %} -{% load i18n static %} -{% block html_title %} - {% block page_title %} - {% translate "Welcome to Servala" %} - {% endblock page_title %} -{% endblock html_title %} -{% block content %} -
- {% if not user_organizations %} -
-
-
-
-

{% translate "Welcome to Servala!" %}

-
-
-
-
- -
-
{% translate "Get Started with Your First Organization" %}
-

- {% blocktranslate trimmed %} - Organizations help you manage your services and resources. - Create your first organization to start using Servala's service catalog. - {% endblocktranslate %} -

- -
-
{% translate "Next Steps" %}
-
-
-
- -
{% translate "Create Organization" %}
- {% translate "Set up your workspace" %} -
-
-
-
- -
{% translate "Discover Services" %}
- {% translate "Browse available services" %} -
-
-
-
- -
{% translate "Create Instances" %}
- {% translate "Deploy your first service" %} -
-
-
-
-
-
-
-
-
- {% else %} -
- {% for organization in user_organizations %} -
-
-
-
- -
-
{{ organization.name }}
-
-
- - - {{ organization.instance_count }} - {% blocktranslate trimmed count count=organization.instance_count %} - instance - {% plural %} - instances - {% endblocktranslate %} - - - - {{ organization.members.count }} - {% blocktranslate trimmed count count=organization.members.count %} - member - {% plural %} - members - {% endblocktranslate %} - -
-
- -
-
-
- {% endfor %} -
-
- {% endif %} -
-{% endblock content %} diff --git a/src/servala/frontend/templates/frontend/organizations/dashboard.html b/src/servala/frontend/templates/frontend/organizations/dashboard.html index b0dd273..88cb596 100644 --- a/src/servala/frontend/templates/frontend/organizations/dashboard.html +++ b/src/servala/frontend/templates/frontend/organizations/dashboard.html @@ -1,258 +1 @@ {% extends "frontend/base.html" %} -{% load i18n static %} -{% block html_title %} - {{ object.name }} {% translate "Dashboard" %} -{% endblock html_title %} -{% block page_title %}{% endblock %} -{% block content %} -
-
-
-
-
-
-
-

{% translate "Welcome to" %} {{ object.name }}

-

- {% if has_instances %} - {% translate "Here's an overview of your organization's services and resources." %} - {% else %} - {% translate "Ready to get started? Discover services and create your first instance." %} - {% endif %} -

-
- {% if user_role %} -
- - {% if user_role == "owner" %} - {% translate "Owner" %} - {% elif user_role == "admin" %} - {% translate "Administrator" %} - {% else %} - {% translate "Member" %} - {% endif %} - -
- {% endif %} -
-
-
-
-
- {% if has_instances %} -
-
-
-
-
-
- -
-
-
{% translate "Service Instances" %}
-

{{ service_instances_count }}

-
-
-
-
-
-
-
-
-
-
- -
-
-
{% translate "Team Members" %}
-

{{ members_count }}

-
-
-
-
-
-
- {% endif %} -
- {% if has_instances %} -
-
-
-

{% translate "Recent Service Instances" %}

-
-
-
- - - - - - - - - - - - {% for instance in service_instances %} - - - - - - - - {% endfor %} - -
{% translate "Name" %}{% translate "Service" %}{% translate "Status" %}{% translate "Created" %}{% translate "Actions" %}
- {{ instance.name }} - -
- {% if instance.context.service_offering.service.logo %} - {{ instance.context.service_offering.service.name }} - {% endif %} - {{ instance.context.service_offering.service.name }} -
-
- {% if instance.is_deleted %} - {% translate "Deleted" %} - {% else %} - {% translate "Active" %} - {% endif %} - - {{ instance.created_at|date:"M d, Y" }} - -
- - - - {% if instance.has_change_permission %} - - - - {% endif %} -
-
-
- -
-
-
- - {% else %} - {# if has_instances #} -
-
-
-

{% translate "Get Started" %}

-
-
-
-
- -
-
{% translate "Ready to deploy your first service?" %}
-

- {% translate "Browse our service catalog and deploy databases, storage, and other services with just a few clicks." %} -

- - - {% translate "Discover Services" %} - -
-
-
-
-
-
-
-

{% translate "Next Steps" %}

-
-
-
-
-
-
-
{% translate "Organization Created" %}
- {% translate "You're all set up!" %} -
-
-
-
-
-
{% translate "Discover Services" %}
- {% translate "Browse what's available" %} -
-
-
-
-
-
{% translate "Deploy Your First Service" %}
- {% translate "Create an instance" %} -
-
-
-
-
-
- {% endif %} -
-
-{% endblock content %} diff --git a/src/servala/frontend/urls.py b/src/servala/frontend/urls.py index 7790b22..52a048e 100644 --- a/src/servala/frontend/urls.py +++ b/src/servala/frontend/urls.py @@ -6,11 +6,6 @@ from servala.frontend import views urlpatterns = [ path("accounts/profile/", views.ProfileView.as_view(), name="profile"), path("accounts/logout/", views.LogoutView.as_view(), name="logout"), - path( - "organizations/", - views.OrganizationSelectionView.as_view(), - name="organization.selection", - ), path( "organizations/create", views.OrganizationCreateView.as_view(), @@ -73,9 +68,5 @@ urlpatterns = [ ] ), ), - path( - "", - RedirectView.as_view(pattern_name="frontend:organization.selection"), - name="index", - ), + path("", RedirectView.as_view(pattern_name="frontend:profile"), name="index"), ] diff --git a/src/servala/frontend/views/__init__.py b/src/servala/frontend/views/__init__.py index 5f11a75..5ae01ec 100644 --- a/src/servala/frontend/views/__init__.py +++ b/src/servala/frontend/views/__init__.py @@ -1,12 +1,5 @@ from .auth import LogoutView -from .generic import ( - IndexView, - OrganizationSelectionView, - ProfileView, - custom_403, - custom_404, - custom_500, -) +from .generic import IndexView, ProfileView, custom_403, custom_404, custom_500 from .organization import ( OrganizationCreateView, OrganizationDashboardView, @@ -28,7 +21,6 @@ __all__ = [ "LogoutView", "OrganizationCreateView", "OrganizationDashboardView", - "OrganizationSelectionView", "OrganizationUpdateView", "ServiceDetailView", "ServiceInstanceDeleteView", diff --git a/src/servala/frontend/views/generic.py b/src/servala/frontend/views/generic.py index 16b1ec2..7d1a3a0 100644 --- a/src/servala/frontend/views/generic.py +++ b/src/servala/frontend/views/generic.py @@ -1,7 +1,5 @@ from django.conf import settings -from django.contrib.auth.mixins import LoginRequiredMixin -from django.db.models import Count, Q -from django.shortcuts import redirect, render +from django.shortcuts import render from django.urls import reverse_lazy from django.utils.functional import cached_property from django.views.generic import TemplateView @@ -15,30 +13,6 @@ class IndexView(TemplateView): template_name = "frontend/index.html" -class OrganizationSelectionView(LoginRequiredMixin, TemplateView): - template_name = "frontend/organization_selection.html" - - @cached_property - def user_organizations(self): - return self.request.user.organizations.all() - - def dispatch(self, request, *args, **kwargs): - # Users with a single organization get redirected to the organization’s dashboard - if self.user_organizations.count() == 1: - organization = self.user_organizations.first() - return redirect(organization.urls.base) - return super().dispatch(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["user_organizations"] = self.user_organizations.annotate( - instance_count=Count( - "service_instances", filter=Q(service_instances__is_deleted=False) - ) - ) - return context - - class ProfileView(HtmxUpdateView): template_name = "frontend/profile.html" form_class = UserProfileForm diff --git a/src/servala/frontend/views/organization.py b/src/servala/frontend/views/organization.py index 6545d39..29eb5f5 100644 --- a/src/servala/frontend/views/organization.py +++ b/src/servala/frontend/views/organization.py @@ -3,12 +3,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView from rules.contrib.views import AutoPermissionRequiredMixin -from servala.core.models import ( - BillingEntity, - Organization, - OrganizationMembership, - ServiceInstance, -) +from servala.core.models import BillingEntity, Organization from servala.frontend.forms.organization import OrganizationCreateForm, OrganizationForm from servala.frontend.views.mixins import HtmxUpdateView, OrganizationViewMixin @@ -66,37 +61,6 @@ class OrganizationDashboardView( ): template_name = "frontend/organizations/dashboard.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - organization = self.get_object() - - service_instances = ServiceInstance.objects.filter( - organization=organization, is_deleted=False - ) - recent_instances = service_instances.order_by("-created_at")[:5] - - for instance in recent_instances: - instance.has_change_permission = self.request.user.has_perm( - "core.change_serviceinstance", instance - ) - - user_membership = OrganizationMembership.objects.filter( - user=self.request.user, organization=organization - ).first() - user_role = user_membership.role if user_membership else None - - context.update( - { - "service_instances_count": service_instances.count(), - "service_instances": recent_instances, - "members_count": organization.members.count(), - "has_instances": service_instances.exists(), - "user_role": user_role, - } - ) - - return context - class OrganizationUpdateView(OrganizationViewMixin, HtmxUpdateView): template_name = "frontend/organizations/update.html" diff --git a/src/servala/static/css/servala.css b/src/servala/static/css/servala.css index db9052a..b7a5b8b 100644 --- a/src/servala/static/css/servala.css +++ b/src/servala/static/css/servala.css @@ -99,78 +99,3 @@ a.btn-keycloak { .hide-form-errors .alert.form-errors { display: none; } -.organization-card { - transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; - cursor: pointer; -} - -.organization-card:hover { - transform: translateY(-5px); - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); -} -.stats-icon { - width: 60px; - height: 60px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.5rem; - color: white; - i::before { - display: block; - margin-top: -4px; - margin-left: -5px; - } -} - -.stats-icon.purple { - background-color: var(--bs-primary); -} - -.stats-icon.blue { - background-color: var(--bs-info); -} - -.stats-icon.green { - background-color: var(--brand-success); -} - -.timeline { - position: relative; - padding-left: 20px; -} - -.timeline::before { - content: ''; - position: absolute; - left: 8px; - top: 0; - bottom: 0; - width: 2px; - background-color: #e5e7eb; -} - -.timeline-item { - position: relative; - margin-bottom: 1rem; -} - -.timeline-marker { - position: absolute; - left: -16px; - width: 16px; - height: 16px; - border-radius: 50%; - background-color: #d1d5db; - border: 3px solid white; - box-shadow: 0 0 0 3px #f3f4f6; -} - -.timeline-content { - margin-left: 10px; -} -.quick-actions i.bi { - margin-top: -16px; - padding-right: 28px; -}