formatting improvements.

This commit is contained in:
2025-11-18 23:11:14 -08:00
parent 5524d7308c
commit 0bb071f337
6 changed files with 660 additions and 407 deletions

View File

@@ -27,18 +27,37 @@ rothbard/
├── generate_sample.py # Utility to generate sample Filevine API responses
├── requirements.txt # Python dependencies
├── rothbard-service-account.json # Firebase service account credentials
├── rothbard-staging2-12345-firebase-adminsdk-fbsvc-7f95268383.json # Firebase service account for staging
├── static/
│ └── auth.js # Client-side authentication handling
├── templates/ # Jinja2 HTML templates
│ ├── base.html # Base template with navigation
│ ├── login.html # Firebase login page
│ ├── welcome.html # User welcome/onboarding page
── dashboard.html # Main case dashboard
── dashboard.html # Main case dashboard
│ ├── admin_users.html # Admin user management interface
│ ├── admin_user_edit.html # Admin user edit interface
│ ├── admin_user_create.html # Admin user creation interface
│ └── _pagination.html # Pagination component
├── examples/ # Sample Filevine API responses
│ ├── project_list.json
│ ├── project_contacts.json
── client.json
└── .env # Environment variables (not tracked)
│ ├── forms__complaintInfo.json
│ ├── forms__newFileReview.json
── project_tasks.json
│ ├── project_type_pahe_list.json
│ ├── project_team.json
│ └── ...
├── .env # Environment variables (not tracked)
├── .gcloudignore # Files ignored by Google Cloud Build
├── .gitignore # Files ignored by Git
├── cloudbuild.yaml # Google Cloud Build configuration
├── Dockerfile # Containerization configuration
├── deploy.sh # Deployment script
├── main.tf # Terraform infrastructure as code
├── firestore.rules # Firestore security rules
├── column_mapping.json # Column mapping configuration (unused)
├── DEPLOY.md # Deployment instructions
├── CLAUDE.md # Development guidance
└── utils.py # Utility functions for user profile management
```
## Core Features
@@ -48,6 +67,7 @@ rothbard/
- Server-side session management with 8-hour expiration
- User profile management in Firestore
- Role-based access control (admin-enabled users only)
- Admin interface for user management
### Case Management Dashboard
- Real-time fetching of projects from Filevine API
@@ -57,6 +77,9 @@ rothbard/
- Project numbers and incident dates
- Contact information and project URLs
- Responsive design using Tailwind CSS
- Configurable column visibility with local storage
- Pagination for large datasets
- Admin simulation mode to view other users' cases
### API Integration
- OAuth 2.0 authentication with Filevine API
@@ -66,6 +89,16 @@ rothbard/
- Individual project details
- Client information
- Project contacts
- Project tasks and forms
### Admin Interface
- Comprehensive user management dashboard
- Enable/disable user access
- Grant/revoke admin privileges
- Reset user passwords
- Create new users
- View all user profiles
- Simulate case email access for testing
## Configuration
@@ -78,11 +111,17 @@ Create a `.env` file with the following variables:
FLASK_SECRET_KEY=your-secret-key-here
# Firebase Configuration
# Choose ONE of these approaches:
# 1) Path to JSON creds file
GOOGLE_APPLICATION_CREDENTIALS=./rothbard-staging2-12345-firebase-adminsdk-fbsvc-7f95268383.json
# 2) Or inline JSON (escaped as single line)
# FIREBASE_SERVICE_ACCOUNT_JSON="{\"type\":\"service_account\",...}"
# Front-end Firebase (public — safe to expose)
FIREBASE_API_KEY=your-firebase-api-key
FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
FIREBASE_PROJECT_ID=your-firebase-project-id
FIREBASE_APP_ID=your-firebase-app-id
FIREBASE_SERVICE_ACCOUNT_JSON='{"type":"service_account",...}' # or set GOOGLE_APPLICATION_CREDENTIALS
# Filevine API Configuration
FILEVINE_CLIENT_ID=your-filevine-client-id
@@ -97,8 +136,9 @@ FILEVINE_USER_ID=your-filevine-user-id
1. Create a Firebase project at https://console.firebase.google.com
2. Enable Authentication with Email/Password provider
3. Create a Firestore database
4. Generate a service account key and save as `rothbard-service-account.json`
4. Generate a service account key and save as `rothbard-staging2-12345-firebase-adminsdk-fbsvc-7f95268383.json`
5. Configure Authentication settings for your web app
6. Set up Firestore security rules (provided in `firestore.rules`)
### Filevine API Setup
@@ -133,7 +173,7 @@ FILEVINE_USER_ID=your-filevine-user-id
```
5. **Initialize Firebase**
- Place your service account JSON file at `rothbard-service-account.json`
- Place your service account JSON file at `rothbard-staging2-12345-firebase-adminsdk-fbsvc-7f95268383.json`
- Or set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable
6. **Run the application**
@@ -158,6 +198,8 @@ FILEVINE_USER_ID=your-filevine-user-id
1. User profiles are stored in Firestore at `users/{uid}`
2. Enable users by setting `enabled: true` and providing a `caseEmail`
3. The `caseEmail` field determines which projects the user can access
4. Admins can access the admin interface at `/admin/users` to manage all users
5. Admins can simulate other users' case access by entering their email in the simulation field on the dashboard
## Development Tools
@@ -169,9 +211,10 @@ python generate_sample.py
```
This will create JSON files in the `examples/` directory containing:
- Sample project lists
- Project contacts
- Client information
- Sample project forms (complaintInfo, newFileReview)
- Project tasks
- Project type phases
- Project team members
These samples are useful for development and testing without hitting the live API.
@@ -183,6 +226,8 @@ These samples are useful for development and testing without hitting the live AP
- User access is controlled through Firestore profiles
- Sensitive credentials are stored in environment variables
- Filevine API tokens are properly scoped and managed
- Firestore security rules restrict access to user's own profile
- Google Cloud Build and deployment use secure practices
## Future Enhancements
@@ -204,6 +249,8 @@ Planned improvements include:
- **python-dotenv 1.0.1** - Environment variable management
- **requests 2.32.3** - HTTP client for API calls
- **itsdangerous 2.2.0** - Security utilities for Flask
- **gunicorn 23.0.0** - WSGI HTTP Server
- **pytz 2024.1** - Timezone library
## API Endpoints
@@ -214,11 +261,19 @@ Planned improvements include:
- `GET /logout` - Session termination
- `GET /welcome` - User onboarding page
- `GET /dashboard` - Main case dashboard (authenticated users only)
- `GET /admin/users` - Admin user management interface
- `GET /admin/users/<uid>` - Admin user detail view
- `POST /admin/users/update` - Update user information
- `POST /admin/users/create` - Create new user
- `POST /admin/users/<uid>/reset-password` - Reset user password
### Filevine API Integration
- Projects: `/fv-app/v2/Projects`
- Project Details: `/fv-app/v2/Projects/{id}`
- Contacts: `/fv-app/v2/projects/{id}/contacts`
- Project Team: `/fv-app/v2/Projects/{id}/team`
- Project Tasks: `/fv-app/v2/Projects/{id}/tasks`
- Project Forms: `/fv-app/v2/Projects/{id}/Forms/{form}`
- Project Contacts: `/fv-app/v2/projects/{id}/contacts`
- Client Info: `/fv-app/v2/contacts/{id}`
## License

43
app.py
View File

@@ -1,61 +1,20 @@
import json
import os
from functools import wraps
from datetime import datetime, timedelta
import pytz
from flask import Flask, render_template, request, redirect, url_for, session, abort, jsonify
from dotenv import load_dotenv
load_dotenv()
import requests
from filevine_client import FilevineClient
from utils import get_user_profile
from firebase_init import db
from firebase_admin import auth as fb_auth
import config
app = Flask(__name__)
app.secret_key = os.environ.get("FLASK_SECRET_KEY", os.urandom(32))
# --- Firebase Admin init --- (moved to firebase_init.py)
# --- Filevine env ---
FV_CLIENT_ID = os.environ.get("FILEVINE_CLIENT_ID")
FV_CLIENT_SECRET = os.environ.get("FILEVINE_CLIENT_SECRET")
FV_PAT = os.environ.get("FILEVINE_PERSONAL_ACCESS_TOKEN")
FV_ORG_ID = os.environ.get("FILEVINE_ORG_ID")
FV_USER_ID = os.environ.get("FILEVINE_USER_ID")
if not all([FV_CLIENT_ID, FV_CLIENT_SECRET, FV_PAT, FV_ORG_ID, FV_USER_ID]):
print("[WARN] Missing one or more Filevine env vars — dashboard will fail until set.")
PHASES = {
209436: "Nonpayment File Review",
209437: "Attorney File Review",
209438: "Notice Preparation",
209439: "Notice Pending",
209440: "Notice Expired",
209442: "Preparing and Filing UD",
209443: "Waiting for Answer",
209444: "Archived",
210761: "Service of Process",
211435: "Default",
211436: "Pre-Answer Motion",
211437: "Request for Trial",
211438: "Trial Prep and Trial",
211439: "Writ and Sheriff",
211440: "Lockout Pending",
211441: "Stipulation Preparation",
211442: "Stipulation Pending",
211443: "Stipulation Expired",
211446: "On Hold",
211466: "Request for Monetary Judgment",
211467: "Appeals and Post-Poss. Motions",
211957: "Migrated",
213691: "Close Out/ Invoicing",
213774: "Judgment After Stip & Order",
}
# --- Helpers ---
def login_required(view):

38
config.py Normal file
View File

@@ -0,0 +1,38 @@
import os
# --- Filevine env ---
FV_CLIENT_ID = os.environ.get("FILEVINE_CLIENT_ID")
FV_CLIENT_SECRET = os.environ.get("FILEVINE_CLIENT_SECRET")
FV_PAT = os.environ.get("FILEVINE_PERSONAL_ACCESS_TOKEN")
FV_ORG_ID = os.environ.get("FILEVINE_ORG_ID")
FV_USER_ID = os.environ.get("FILEVINE_USER_ID")
if not all([FV_CLIENT_ID, FV_CLIENT_SECRET, FV_PAT, FV_ORG_ID, FV_USER_ID]):
print("[WARN] Missing one or more Filevine env vars — dashboard will fail until set.")
PHASES = {
209436: "Nonpayment File Review",
209437: "Attorney File Review",
209438: "Notice Preparation",
209439: "Notice Pending",
209440: "Notice Expired",
209442: "Preparing and Filing UD",
209443: "Waiting for Answer",
209444: "Archived",
210761: "Service of Process",
211435: "Default",
211436: "Pre-Answer Motion",
211437: "Request for Trial",
211438: "Trial Prep and Trial",
211439: "Writ and Sheriff",
211440: "Lockout Pending",
211441: "Stipulation Preparation",
211442: "Stipulation Pending",
211443: "Stipulation Expired",
211446: "On Hold",
211466: "Request for Monetary Judgment",
211467: "Appeals and Post-Poss. Motions",
211957: "Migrated",
213691: "Close Out/ Invoicing",
213774: "Judgment After Stip & Order",
}

View File

@@ -40,7 +40,7 @@ def convert_to_pacific_time(date_str):
pacific_time = utc_time.astimezone(pytz.timezone('America/Los_Angeles'))
# Format as YYYY-MM-DD
return pacific_time.strftime('%Y-%m-%d')
return pacific_time.strftime('%d/%m/%Y')
except (ValueError, AttributeError) as e:
print(f"[WARN] Date conversion failed for '{date_str}': {e}")
return ''

6
templates/_expander.html Normal file
View File

@@ -0,0 +1,6 @@
{% macro expander() %}
<div x-ref="content" class="content relative overflow-hidden transition-all duration-500"
:class="expanded ? 'max-h-100' : 'max-h-[3em]'">
{{ caller() }}
<div>
{% endmacro %}

View File

@@ -7,9 +7,7 @@
{% if profile.is_admin %}
<div class="mb-4 flex w-[400px]">
<label for="simulateCaseEmail" class=" text-sm font-medium text-slate-700 mb-1">Simulate case email:</label>
<input type="text"
id="simulateCaseEmail"
x-model="case_email_sim"
<input type="text" id="simulateCaseEmail" x-model="case_email_sim"
@keyup.debounce.1000ms="window.location.href=`/dashboard/1?case_email=${encodeURIComponent($data.case_email_sim)}`"
class="w-full px-3 py-2 border w-64 border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Enter case email to simulate">
@@ -18,16 +16,13 @@
<!-- Configure Visible Columns Link -->
<div class="mb-4">
<button @click="showColumnModal = true"
class="text-blue-600 hover:text-blue-800 text-sm font-medium underline">
<button @click="showColumnModal = true" class="text-blue-600 hover:text-blue-800 text-sm font-medium underline">
Configure Visible Columns...
</button>
</div>
<!-- Column Configuration Modal -->
<div x-show="showColumnModal"
x-cloak
x-transition
<div x-show="showColumnModal" x-cloak x-transition
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
@click.self="showColumnModal = false">
<div class="bg-white rounded-lg p-6 max-w-2xl w-full max-h-[80vh] overflow-y-auto">
@@ -42,9 +37,7 @@
<div class="mb-4">
<label class="flex items-center">
<input type="checkbox"
x-model="selectAll"
@change="toggleAllColumns()"
<input type="checkbox" x-model="selectAll" @change="toggleAllColumns()"
class="mr-2 rounded border-gray-300 text-blue-600 focus:ring-blue-500">
<span class="text-sm font-medium">Select All / Deselect All</span>
</label>
@@ -53,10 +46,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 max-h-96 overflow-y-auto">
<template x-for="(column, index) in columns" :key="index">
<label class="flex items-center p-2 hover:bg-slate-50 rounded cursor-pointer">
<input type="checkbox"
:value="column"
x-model="visibleColumns"
@change="saveColumnSettings()"
<input type="checkbox" :value="column" x-model="visibleColumns" @change="saveColumnSettings()"
:checked="visibleColumns.includes(column)"
class="mr-2 rounded border-gray-300 text-blue-600 focus:ring-blue-500">
<span class="text-sm" x-text="column"></span>
@@ -76,91 +66,160 @@
</div>
</div>
</div>
{% from "_expander.html" import expander %}
<div class="overflow-scroll">
<table class="w-full whitespace-nowrap shadow-md border border-slate-200">
<thead class=" text-left text-sm sticky top-0 z-10 border-b border-blue-800 text-white font-medium"
<table class="w-full table-fixed shadow-md border border-slate-200">
<thead class=" text-left text-sm z-10 border-b border-blue-800 text-white font-medium"
style="background-color: rgb(89, 121, 142);">
<tr>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Matter Num')}">Matter Num</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Client / Property')}">Client / Property</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Matter Description')}">Matter Description</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Defendant 1')}">Defendant 1</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Matter Open')}">Matter Open</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Practice Area')}">Practice Area</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Notice Type')}">Notice Type</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Case Number')}">Case Number</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Premises Address')}">Premises Address</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Premises City')}">Premises City</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Assigned Attorney')}">Assigned Attorney</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Primary Contact')}">Primary Contact</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Secondary Paralegal')}">Secondary Paralegal</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Documents')}">Documents</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Matter Stage')}">Matter Stage</th>
<th class="px-4 py-3 w-[400px]" :class="{'hidden': !isColumnVisible('Completed Tasks')}">Completed Tasks</th>
<th class="px-4 py-3 w-[400px]" :class="{'hidden': !isColumnVisible('Pending Tasks')}">Pending Tasks</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Notice Service Date')}">Notice Service Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Notice Expir. Date')}">Notice Expir. Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Date Case Filed')}">Date Case Filed</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Daily Rent Damages')}">Daily Rent Damages</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Default Date')}">Default Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Default Entered On')}">Default Entered On</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Motions:')}">Motions:</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Demurrer Hearing Date')}">Demurrer Hearing Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Motion To Strike Hearing Date')}">Motion To Strike Hearing Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Motion to Quash Hearing Date')}">Motion to Quash Hearing Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Other Motion Hearing Date')}">Other Motion Hearing Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('MSC Date')}">MSC Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('MSC Time')}">MSC Time</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('MSC Address')}">MSC Address</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('MSC Div/ Dept/ Room')}">MSC Div/ Dept/ Room</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Trial Date')}">Trial Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Trial Time')}">Trial Time</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Trial Address')}">Trial Address</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Trial Div/ Dept/ Room')}">Trial Div/ Dept/ Room</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Final Result of Trial/ MSC')}">Final Result of Trial/ MSC</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Date of Settlement')}">Date of Settlement</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Final Obligation Under the Stip')}">Final Obligation Under the Stip</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Def\'s Comply with the Stip?')}">Def's Comply with the Stip?</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Judgment Date')}">Judgment Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Writ Issued Date')}">Writ Issued Date</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Scheduled Lockout')}">Scheduled Lockout</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Oppose Stays?')}">Oppose Stays?</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Premises Safety or Access Issues')}">Premises Safety or Access Issues</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Matter Gate or Entry Code')}">Matter Gate or Entry Code</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Date Possession Recovered')}">Date Possession Recovered</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Attorney\'s Fees')}">Attorney's Fees</th>
<th class="px-4 py-3" :class="{'hidden': !isColumnVisible('Costs')}">Costs</th>
<th class="px-4 py-3 w-16 sticky left-0 top-0 z-[40]" style="background-color: rgb(89, 121, 142);"></th>
<th class="px-4 py-3 w-32 sticky left-16 top-0 z-[40]" style="background-color: rgb(89, 121, 142);" :class="{'hidden': !isColumnVisible('Matter Num')}">Matter Num</th>
<th class="px-4 py-3 w-64 sticky left-48 top-0 z-[40]" style="background-color: rgb(89, 121, 142);" :class="{'hidden': !isColumnVisible('Client / Property')}">Client / Property</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-72 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Matter Description')}">Matter Description</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Defendant 1')}">Defendant 1</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Matter Open')}">Matter Open</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Practice Area')}">Practice Area</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-64 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Notice Type')}">Notice Type</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Case Number')}">Case Number</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-72 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Premises Address')}">Premises Address</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isCstyle="background-color: rgb(89, 121, 142);" olumnVisible('Premises City')}">Premises City</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Assigned Attorney')}">Assigned Attorney</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Primary Contact')}">Primary Contact</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Secondary Paralegal')}">Secondary Paralegal</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Documents')}">Documents</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-64 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Matter Stage')}">Matter Stage</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-[400px] sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Completed Tasks')}">Completed Tasks</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-[400px] sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Pending Tasks')}">Pending Tasks</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Notice Service Date')}">Notice Service Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Notice Expir. Date')}">Notice Expir. Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Date Case Filed')}">Date Case Filed</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Daily Rent Damages')}">Daily Rent Damages</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Default Date')}">Default Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Default Entered On')}">Default Entered On</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Motions:')}">Motions:</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Demurrer Hearing Date')}">Demurrer Hearing Date </th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Motion To Strike Hearing Date')}">Motion To Strike Hearing Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Motion to Quash Hearing Date')}">Motion to Quash Hearing Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Other Motion Hearing Date')}">Other Motion Hearing Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('MSC Date')}">MSC Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('MSC Time')}">MSC Time</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-72 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('MSC Address')}">MSC Address</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('MSC Div/ Dept/ Room')}">MSC Div/ Dept/ Room</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Trial Date')}">Trial Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Trial Time')}">Trial Time</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-72 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Trial Address')}">Trial Address</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Trial Div/ Dept/ Room')}">Trial Div/ Dept/ Room </th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-48 sticky top-0 z-[40]" :class="{'hidden': !isColumnVisible('Final Result of Trial/ MSC')}">Final Result of Trial/ MSC</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Date of Settlement')}">Date of Settlement</th> <th class="px-4 py-3 w-32" :class="{'hidden': !isColumnVisible('Final Obligation Under the Stip')}">Final Obligation Under the Stip</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Def\'s Comply with the Stip?')}">Def's Comply with the Stip?</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Judgment Date')}">Judgment Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Writ Issued Date')}">Writ Issued Date</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Scheduled Lockout')}">Scheduled Lockout</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Oppose Stays?')}">Oppose Stays?</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-64 sticky top-0" :class="{'hidden': !isColumnVisible('Premises Safety or Access Issues')}">Premises Safety or Access Issues</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-64 sticky top-0" :class="{'hidden': !isColumnVisible('Matter Gate or Entry Code')}">Matter Gate or Entry Code</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Date Possession Recovered')}">Date Possession Recovered</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Attorney\'s Fees')}">Attorney's Fees</th>
<th style="background-color: rgb(89, 121, 142);" class="px-4 py-3 w-32 sticky top-0" :class="{'hidden': !isColumnVisible('Costs')}">Costs</th>
</tr>
</thead>
<tbody class="bg-slate-100 divide-y divide-slate-300">
{% for r in rows %}
<tr class="hover:bg-slate-200 transition-colors duration-150 ease-in-out">
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Num')}">{{ r.number }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Client / Property')}">{{ r.client }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Description')}">{{ r.matter_description }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Defendant 1')}">{{ r.defendant_1 }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Open')}">{{ r.matter_open }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Practice Area')}"></td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Notice Type')}">{{ r.notice_type }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Case Number')}">{{ r.case_number }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Premises Address')}">{{ r.premises_address }}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Premises City')}">{{ r.premises_city }}</td>
<tr class="hover:bg-slate-200 transition-colors duration-150 ease-in-out group"
x-data="{ expanded: false, hasOverflow: false }" x-init="
$nextTick(() => {
// Check overflow for ANY td in this row
const tds = $el.querySelectorAll('td .content');
hasOverflow = Array.from(tds).some(td => td.scrollHeight > td.clientHeight + 1);
});
">
<td class="px-4 py-3 sticky left-0 bg-slate-100 z-[30] group-hover:bg-slate-200 ease-in-out duration-150 transition-colors">
<button x-show="hasOverflow" x-on:click="expanded = !expanded"
class="mt-1 h-5 w-5 flex items-center justify-center rounded border cursor-pointer text-xs">
<span class="inline-block transition-transform duration-150" :class="expanded ? 'rotate-90' : ''"></span>
</button>
</td>
<td class="px-4 py-3 text-sm text-slate-800 left-16 bg-slate-100 sticky z-[30] group-hover:bg-slate-200 ease-in-out duration-150 transition-colors" :class="{'hidden': !isColumnVisible('Matter Num')}">
{{ r.number }}
</td>
<td class="px-4 py-3 text-sm text-slate-800 sticky bg-slate-100 left-48 w-64 z-[30] group-hover:bg-slate-200 ease-in-out duration-150 transition-colors" :class="{'hidden': !isColumnVisible('Client / Property')}">
{% call expander() %}
{{ r.client }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800 w-64"
:class="{'hidden': !isColumnVisible('Matter Description')}">
{% call expander() %}
{{ r.matter_description }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Defendant 1')}">
{% call expander() %}
{{ r.defendant_1 }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Open')}">
{% call expander() %}
{{ r.matter_open }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Practice Area')}">
{% call expander() %}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Notice Type')}">
{% call expander() %}
{{ r.notice_type }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Case Number')}">
{% call expander() %}
{{ r.case_number }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800 w-[200px]" :class="{'hidden': !isColumnVisible('Premises Address')}">
{% call expander() %}
{{ r.premises_address }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Premises City')}">
{% call expander() %}
{{ r.premises_city }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Assigned Attorney')}">
{% call expander() %}
{{ r.responsible_attorney }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Primary Contact')}">
{% call expander() %}
{{ r.staff_person }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Secondary Paralegal')}">
{% call expander() %}
{{ r.staff_person_2 }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Documents')}">
{% call expander() %}
{% endcall %}
{% if r.documents_url %}
<a href="{{ r.documents_url }}">Documents</a>
{% endif %}</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Stage')}"> {{ r.phase_name }}</td>
<td class="px-4 py-3 text-sm align-top whitespace-normal w-[400px]" :class="{'hidden': !isColumnVisible('Completed Tasks')}" x-data="{ showCompletedModal: false}">
<a class="text-blue-500 text-underline" href=" {{ r.documents_url }}">Documents</a>
{% endif %}
</td>
<td class="px-4 py-3 text-sm text-slate-800" :class="{'hidden': !isColumnVisible('Matter Stage')}">
{% call expander() %}
{{ r.phase_name }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm align-top whitespace-normal w-[400px]"
:class="{'hidden': !isColumnVisible('Completed Tasks')}" x-data="{ showCompletedModal: false}">
{% call expander() %}
{% if r.completed_tasks %}
<div>
<table class="w-full text-xs">
@@ -180,13 +239,12 @@
</tbody>
</table>
{% if r.completed_tasks|length > 2 %}
<button @click="showCompletedModal = true" class="text-blue-500 hover:text-blue-700 text-sm mt-1">Show more...</button>
<button @click="showCompletedModal = true" class="text-blue-500 hover:text-blue-700 text-sm mt-1">Show
more...</button>
{% endif %}
</div>
<div x-show="showCompletedModal"
x-cloak
x-transition
<div x-show="showCompletedModal" x-cloak x-transition
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
@click.self="showCompletedModal = false">
<div class="bg-white rounded-lg p-6 max-w-lg w-full max-h-[80vh] overflow-y-auto">
@@ -194,7 +252,8 @@
<h3 class="text-lg font-semibold">Completed Tasks</h3>
<button @click="showCompletedModal = false" class="text-gray-500 hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</button>
</div>
@@ -217,8 +276,12 @@
</div>
</div>
{% endif %}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm align-top whitespace-normal w-[400px] min-w-[400px]" :class="{'hidden': !isColumnVisible('Pending Tasks')}" x-data="{ showPendingModal: false }">
<td class="px-4 py-3 text-sm align-top whitespace-normal w-[400px] min-w-[400px]"
:class="{'hidden': !isColumnVisible('Pending Tasks')}" x-data="{ showPendingModal: false }">
{% call expander() %}
{% if r.pending_tasks %}
<div>
<table class="w-full text-xs">
@@ -236,13 +299,12 @@
</tbody>
</table>
{% if r.pending_tasks|length > 2 %}
<button @click="showPendingModal = true" class="text-blue-500 hover:text-blue-700 text-sm mt-1">Show more...</button>
<button @click="showPendingModal = true" class="text-blue-500 hover:text-blue-700 text-sm mt-1">Show
more...</button>
{% endif %}
</div>
<div x-show="showPendingModal"
x-cloak
x-transition
<div x-show="showPendingModal" x-cloak x-transition
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
@click.self="showPendingModal = false">
<div class="bg-white rounded-lg p-6 max-w-lg w-full max-h-[80vh] overflow-y-auto">
@@ -250,7 +312,8 @@
<h3 class="text-lg font-semibold">Pending Tasks</h3>
<button @click="showPendingModal = false" class="text-gray-500 hover:text-gray-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</button>
</div>
@@ -271,39 +334,170 @@
</div>
</div>
{% endif %}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Notice Service Date')}">
{% call expander() %}
{{ r.notice_service_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Notice Expir. Date')}">
{% call expander() %}
{{ r.notice_expiration_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date Case Filed')}">
{% call expander() %}
{{ r.case_field_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Daily Rent Damages')}">
{% call expander() %}
{% if r.daily_rent_damages %}${{ "{:,.2f}".format(r.daily_rent_damages) }}{% endif %}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Default Date')}">
{% call expander() %}
{{ r.default_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Default Entered On')}">
{% call expander() %}
{{ r.default_entered_on_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Notice Service Date')}">{{ r.notice_service_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Notice Expir. Date')}">{{ r.notice_expiration_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date Case Filed')}">{{ r.case_field_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Daily Rent Damages')}">{% if r.daily_rent_damages %}${{ "{:,.2f}".format(r.daily_rent_damages) }}{% endif %}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Default Date')}">{{ r.default_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Default Entered On')}">{{ r.default_entered_on_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Motions:')}"></td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Demurrer Hearing Date')}">{{ r.demurrer_hearing_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Motion To Strike Hearing Date')}">{{ r.motion_to_strike_hearing_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Motion to Quash Hearing Date')}">{{ r.motion_to_quash_hearing_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Other Motion Hearing Date')}">{{ r.other_motion_hearing_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Date')}">{{ r.msc_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Time')}">{{ r.msc_time }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Address')}">{{ r.msc_address }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Div/ Dept/ Room')}">{{ r.msc_div_dept_room }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Date')}">{{ r.trial_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Time')}">{{ r.trial_time }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Address')}">{{ r.trial_address }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Div/ Dept/ Room')}">{{ r.trial_div_dept_room }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Final Result of Trial/ MSC')}">{{ r.final_result }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date of Settlement')}">{{ r.date_of_settlement }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Final Obligation Under the Stip')}">{{ r.final_obligation }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Def\'s Comply with the Stip?')}">{{ r.def_comply_stip }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Judgment Date')}">{{ r.judgment_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Writ Issued Date')}">{{ r.writ_issued_date }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Scheduled Lockout')}">{{ r.scheduled_lockout }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Oppose Stays?')}">{{ r.oppose_stays }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Premises Safety or Access Issues')}">{{ r.premises_safety }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Matter Gate or Entry Code')}">{{ r.matter_gate_code }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date Possession Recovered')}">{{ r.date_possession_recovered }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Attorney\'s Fees')}">{{ r.attorney_fees }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Costs')}">{{ r.costs }}</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Demurrer Hearing Date')}">
{% call expander() %}
{{ r.demurrer_hearing_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Motion To Strike Hearing Date')}">
{% call expander() %}
{{ r.motion_to_strike_hearing_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Motion to Quash Hearing Date')}">
{% call expander() %}
{{ r.motion_to_quash_hearing_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Other Motion Hearing Date')}">
{% call expander() %}
{{ r.other_motion_hearing_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Date')}">
{% call expander() %}
{{ r.msc_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Time')}">
{% call expander() %}
{{ r.msc_time }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Address')}">
{% call expander() %}
{{ r.msc_address }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('MSC Div/ Dept/ Room')}">
{% call expander() %}
{{ r.msc_div_dept_room }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Date')}">
{% call expander() %}
{{ r.trial_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Time')}">
{% call expander() %}
{{ r.trial_time }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Address')}">
{% call expander() %}
{{ r.trial_address }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Trial Div/ Dept/ Room')}">
{% call expander() %}
{{ r.trial_div_dept_room }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Final Result of Trial/ MSC')}">
{% call expander() %}
{{ r.final_result }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date of Settlement')}">
{% call expander() %}
{{ r.date_of_settlement }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Final Obligation Under the Stip')}">
{% call expander() %}
{{ r.final_obligation }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Def\'s Comply with the Stip?')}">
{% call expander() %}
{{ r.def_comply_stip }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Judgment Date')}">
{% call expander() %}
{{ r.judgment_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Writ Issued Date')}">
{% call expander() %}
{{ r.writ_issued_date }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Scheduled Lockout')}">
{% call expander() %}
{{ r.scheduled_lockout }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Oppose Stays?')}">
{% call expander() %}
{{ r.oppose_stays }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Premises Safety or Access Issues')}">
{% call expander() %}
{{ r.premises_safety }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Matter Gate or Entry Code')}">
{% call expander() %}
{{ r.matter_gate_code }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Date Possession Recovered')}">
{% call expander() %}
{{ r.date_possession_recovered }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Attorney\'s Fees')}">
{% call expander() %}
{{ r.attorney_fees }}
{% endcall %}
</td>
<td class="px-4 py-3 text-sm" :class="{'hidden': !isColumnVisible('Costs')}">
{% call expander() %}
{{ r.costs }}
{% endcall %}
</td>
</tr>
{% else %}
<tr>
@@ -408,12 +602,13 @@ function columnConfig() {
},
toggleAllColumns() {
if (this.selectAll) {
this.visibleColumns = [];
} else {
if (this.visibleColumns.length === 0) {
this.visibleColumns = [...this.columns];
this.selectAll = true;
} else {
this.visibleColumns = [];
this.selectAll = false;
}
this.selectAll = !this.selectAll;
this.saveColumnSettings();
},