update sidebar layout, update theme, update client table data
This commit is contained in:
parent
011080e0f8
commit
1a837ffcfc
4 changed files with 109 additions and 63 deletions
|
|
@ -154,67 +154,71 @@ def get_client(client_name):
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_clients_table_data(filters={}, sortings=[], page=1, page_size=10):
|
def get_clients_table_data(filters={}, sortings=[], page=1, page_size=10):
|
||||||
"""Get paginated client table data with filtering and sorting support."""
|
"""Get paginated client table data with filtering and sorting support."""
|
||||||
# try:
|
try:
|
||||||
|
|
||||||
# print("DEBUG: Raw client table query received:", {
|
print("DEBUG: Raw client table query received:", {
|
||||||
# "filters": filters,
|
"filters": filters,
|
||||||
# "sortings": sortings,
|
"sortings": sortings,
|
||||||
# "page": page,
|
"page": page,
|
||||||
# "page_size": page_size
|
"page_size": page_size
|
||||||
# })
|
})
|
||||||
|
|
||||||
# processed_filters, processed_sortings, is_or, page, page_size = process_query_conditions(filters, sortings, page, page_size)
|
processed_filters, processed_sortings, is_or, page, page_size = process_query_conditions(filters, sortings, page, page_size)
|
||||||
# print("DEBUG: Processed filters:", processed_filters)
|
print("DEBUG: Processed filters:", processed_filters)
|
||||||
# print("DEBUG: Processed sortings:", processed_sortings)
|
print("DEBUG: Processed sortings:", processed_sortings)
|
||||||
# # Handle count with proper OR filter support
|
# Handle count with proper OR filter support
|
||||||
# if is_or:
|
if is_or:
|
||||||
# count = frappe.db.sql(*get_count_or_filters("Address", processed_filters))[0][0]
|
count = frappe.db.sql(*get_count_or_filters("Address", processed_filters))[0][0]
|
||||||
# else:
|
else:
|
||||||
# count = frappe.db.count("Address", filters=processed_filters)
|
count = frappe.db.count("Address", filters=processed_filters)
|
||||||
|
|
||||||
# print("DEBUG: Count of addresses matching filters:", count)
|
print("DEBUG: Count of addresses matching filters:", count)
|
||||||
|
|
||||||
# address_names = frappe.db.get_all(
|
address_names = frappe.db.get_all(
|
||||||
# "Address",
|
"Address",
|
||||||
# fields=["name"],
|
fields=["name"],
|
||||||
# filters=processed_filters if not is_or else None,
|
filters=processed_filters if not is_or else None,
|
||||||
# or_filters=processed_filters if is_or else None,
|
or_filters=processed_filters if is_or else None,
|
||||||
# limit=page_size,
|
limit=page_size,
|
||||||
# start=(page - 1) * page_size,
|
start=(page - 1) * page_size,
|
||||||
# order_by=processed_sortings
|
order_by=processed_sortings
|
||||||
# )
|
)
|
||||||
|
|
||||||
# addresses = [frappe.get_doc("Address", addr["name"]).as_dict() for addr in address_names]
|
addresses = [frappe.get_doc("Address", addr["name"]).as_dict() for addr in address_names]
|
||||||
# tableRows = []
|
tableRows = []
|
||||||
# for address in addresses:
|
for address in addresses:
|
||||||
# tableRow = {}
|
is_lead = False
|
||||||
# links = address.links
|
tableRow = {}
|
||||||
# customer_links = [link for link in links if link.link_doctype == "Customer"] if links else None
|
links = address.links
|
||||||
# customer_name = address.get("custom_customer_to_bill")
|
customer_links = [link for link in links if link.link_doctype == "Customer"] if links else None
|
||||||
# if not customer_name and not customer_links:
|
customer_name = address.get("custom_customer_to_bill", None)
|
||||||
# print("DEBUG: No customer links found and no customer to bill.")
|
if not customer_links:
|
||||||
# customer_name = "N/A"
|
customer_links = [link for link in links if link.link_doctype == "Lead"] if links else None
|
||||||
# elif not customer_name and customer_links:
|
is_lead = True if customer_links else False
|
||||||
# print("DEBUG: No customer to bill. Customer links found:", customer_links)
|
if not customer_name and not customer_links:
|
||||||
# customer_name = customer_links[0].link_name
|
print("DEBUG: No customer links found and no customer to bill.")
|
||||||
# tableRow["id"] = address["name"]
|
customer_name = "N/A"
|
||||||
# tableRow["customer_name"] = customer_name
|
elif not customer_name and customer_links:
|
||||||
# tableRow["address"] = (
|
print("DEBUG: No customer to bill. Customer links found:", customer_links)
|
||||||
# f"{address['address_line1']}"
|
customer_name = frappe.get_value("Lead", customer_links[0].link_name, "lead_name") if is_lead else customer_links[0].link_name
|
||||||
# f"{' ' + address['address_line2'] if address['address_line2'] else ''} "
|
tableRow["id"] = address["name"]
|
||||||
# f"{address['city']}, {address['state']} {address['pincode']}"
|
tableRow["customer_name"] = customer_name
|
||||||
# )
|
tableRow["address"] = (
|
||||||
# tableRow["appointment_scheduled_status"] = address.custom_onsite_meeting_scheduled
|
f"{address['address_line1']}"
|
||||||
# tableRow["estimate_sent_status"] = address.custom_estimate_sent_status
|
f"{' ' + address['address_line2'] if address['address_line2'] else ''} "
|
||||||
# tableRow["job_status"] = address.custom_job_status
|
f"{address['city']}, {address['state']} {address['pincode']}"
|
||||||
# tableRow["payment_received_status"] = address.custom_payment_received_status
|
)
|
||||||
# tableRows.append(tableRow)
|
tableRow["appointment_scheduled_status"] = address.custom_onsite_meeting_scheduled
|
||||||
# tableDataDict = build_datatable_dict(data=tableRows, count=count, page=page, page_size=page_size)
|
tableRow["estimate_sent_status"] = address.custom_estimate_sent_status
|
||||||
# return build_success_response(tableDataDict)
|
tableRow["job_status"] = address.custom_job_status
|
||||||
# except frappe.ValidationError as ve:
|
tableRow["payment_received_status"] = address.custom_payment_received_status
|
||||||
# return build_error_response(str(ve), 400)
|
tableRows.append(tableRow)
|
||||||
# except Exception as e:
|
tableDataDict = build_datatable_dict(data=tableRows, count=count, page=page, page_size=page_size)
|
||||||
# return build_error_response(str(e), 500)
|
return build_success_response(tableDataDict)
|
||||||
|
except frappe.ValidationError as ve:
|
||||||
|
return build_error_response(str(ve), 400)
|
||||||
|
except Exception as e:
|
||||||
|
return build_error_response(str(e), 500)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ const notificationStore = useNotificationStore();
|
||||||
const toast = ref();
|
const toast = ref();
|
||||||
const companyStore = useCompanyStore();
|
const companyStore = useCompanyStore();
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
|
const sidebarCollapsed = ref(false);
|
||||||
|
|
||||||
// Connect the toast instance to the store when component mounts
|
// Connect the toast instance to the store when component mounts
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
@ -46,8 +47,8 @@ watchEffect(() => {
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div id="snw-ui">
|
<div id="snw-ui">
|
||||||
<div class="sidebar-column">
|
<div class="sidebar-column" :class="{ collapsed: sidebarCollapsed }">
|
||||||
<SideBar />
|
<SideBar @toggle="sidebarCollapsed = $event" />
|
||||||
</div>
|
</div>
|
||||||
<div id="display-content">
|
<div id="display-content">
|
||||||
<ScrollPanel style="width: 100%; height: 100%">
|
<ScrollPanel style="width: 100%; height: 100%">
|
||||||
|
|
@ -82,21 +83,53 @@ watchEffect(() => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
background: var(--theme-gradient);
|
background: var(--theme-background-gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-column {
|
.sidebar-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
width: 170px;
|
||||||
min-width: 170px;
|
min-width: 170px;
|
||||||
|
transition: width 0.3s ease, min-width 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-column.collapsed {
|
||||||
|
width: 56px;
|
||||||
|
min-width: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.sidebar-column {
|
||||||
|
width: 140px;
|
||||||
|
min-width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-column.collapsed {
|
||||||
|
width: 56px;
|
||||||
|
min-width: 56px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.sidebar-column {
|
||||||
|
width: 120px;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-column.collapsed {
|
||||||
|
width: 56px;
|
||||||
|
min-width: 56px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#display-content {
|
#display-content {
|
||||||
/* flex-grow: 1; */
|
flex-grow: 1;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
max-width: 50vw;
|
max-width: 100%;
|
||||||
min-width: 80%;
|
min-width: 80%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ import {
|
||||||
} from "@iconoir/vue";
|
} from "@iconoir/vue";
|
||||||
import SidebarSpeedDial from "./SidebarSpeedDial.vue";
|
import SidebarSpeedDial from "./SidebarSpeedDial.vue";
|
||||||
|
|
||||||
|
const emit = defineEmits(['toggle']);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const modalStore = useModalStore();
|
const modalStore = useModalStore();
|
||||||
const notifications = useNotificationStore();
|
const notifications = useNotificationStore();
|
||||||
|
|
@ -40,6 +42,7 @@ const focusClientInput = (inputId) => {
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleSidebar = () => {
|
||||||
isCollapsed.value = !isCollapsed.value;
|
isCollapsed.value = !isCollapsed.value;
|
||||||
|
emit('toggle', isCollapsed.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openSidebarAndDial = (category) => {
|
const openSidebarAndDial = (category) => {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ const themeMap = {
|
||||||
secondaryGradientStart: "#2c9b64",
|
secondaryGradientStart: "#2c9b64",
|
||||||
secondaryGradientEnd: "#38c487",
|
secondaryGradientEnd: "#38c487",
|
||||||
secondaryGradient: "linear-gradient(90deg, #2c9b64 0%, #38c487 100%)",
|
secondaryGradient: "linear-gradient(90deg, #2c9b64 0%, #38c487 100%)",
|
||||||
|
backgroundGradient: "linear-gradient(90deg, #f0f8ff 0%, #e6f3ff 100%)",
|
||||||
surface: "#cadcf1ff",
|
surface: "#cadcf1ff",
|
||||||
surfaceAlt: "#dbfdefff",
|
surfaceAlt: "#dbfdefff",
|
||||||
border: "#cfe5f7",
|
border: "#cfe5f7",
|
||||||
|
|
@ -32,6 +33,7 @@ const themeMap = {
|
||||||
secondaryGradientStart: "#d2a106",
|
secondaryGradientStart: "#d2a106",
|
||||||
secondaryGradientEnd: "#f7de6d",
|
secondaryGradientEnd: "#f7de6d",
|
||||||
secondaryGradient: "linear-gradient(90deg, #d2a106 0%, #f7de6d 100%)",
|
secondaryGradient: "linear-gradient(90deg, #d2a106 0%, #f7de6d 100%)",
|
||||||
|
backgroundGradient: "linear-gradient(90deg, #f8fff0 0%, #f0f8e6 100%)",
|
||||||
surface: "#f7fbe9",
|
surface: "#f7fbe9",
|
||||||
surfaceAlt: "#f1f4d6",
|
surfaceAlt: "#f1f4d6",
|
||||||
border: "#dfe8b5",
|
border: "#dfe8b5",
|
||||||
|
|
@ -52,6 +54,7 @@ const themeMap = {
|
||||||
secondaryGradientStart: "#4f8ee5",
|
secondaryGradientStart: "#4f8ee5",
|
||||||
secondaryGradientEnd: "#5fa4ff",
|
secondaryGradientEnd: "#5fa4ff",
|
||||||
secondaryGradient: "linear-gradient(90deg, #4f8ee5 0%, #5fa4ff 100%)",
|
secondaryGradient: "linear-gradient(90deg, #4f8ee5 0%, #5fa4ff 100%)",
|
||||||
|
backgroundGradient: "linear-gradient(90deg, #f5f7fb 0%, #e7ecf5 100%)",
|
||||||
surface: "#f5f7fb",
|
surface: "#f5f7fb",
|
||||||
surfaceAlt: "#e7ecf5",
|
surfaceAlt: "#e7ecf5",
|
||||||
border: "#ced6e5",
|
border: "#ced6e5",
|
||||||
|
|
@ -72,6 +75,7 @@ const themeMap = {
|
||||||
secondaryGradientStart: "#b2a89c",
|
secondaryGradientStart: "#b2a89c",
|
||||||
secondaryGradientEnd: "#cfc6b8",
|
secondaryGradientEnd: "#cfc6b8",
|
||||||
secondaryGradient: "linear-gradient(90deg, #b2a89c 0%, #cfc6b8 100%)",
|
secondaryGradient: "linear-gradient(90deg, #b2a89c 0%, #cfc6b8 100%)",
|
||||||
|
backgroundGradient: "linear-gradient(90deg, #f7f5f2 0%, #ebe6df 100%)",
|
||||||
surface: "#f7f5f2",
|
surface: "#f7f5f2",
|
||||||
surfaceAlt: "#ebe6df",
|
surfaceAlt: "#ebe6df",
|
||||||
border: "#d8d0c5",
|
border: "#d8d0c5",
|
||||||
|
|
@ -92,6 +96,7 @@ const themeMap = {
|
||||||
secondaryGradientStart: "#f28c28",
|
secondaryGradientStart: "#f28c28",
|
||||||
secondaryGradientEnd: "#ffc174",
|
secondaryGradientEnd: "#ffc174",
|
||||||
secondaryGradient: "linear-gradient(90deg, #f28c28 0%, #ffc174 100%)",
|
secondaryGradient: "linear-gradient(90deg, #f28c28 0%, #ffc174 100%)",
|
||||||
|
backgroundGradient: "linear-gradient(90deg, #f8fbf4 0%, #f2f1e9 100%)",
|
||||||
surface: "#f8fbf4",
|
surface: "#f8fbf4",
|
||||||
surfaceAlt: "#f2f1e9",
|
surfaceAlt: "#f2f1e9",
|
||||||
border: "#d9e5cc",
|
border: "#d9e5cc",
|
||||||
|
|
@ -105,11 +110,11 @@ const themeMap = {
|
||||||
|
|
||||||
export const useThemeStore = defineStore("theme", {
|
export const useThemeStore = defineStore("theme", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
currentTheme: themeMap.SprinklersNW,
|
currentTheme: themeMap["Sprinklers Northwest"],
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
applyTheme(companyName) {
|
applyTheme(companyName) {
|
||||||
const theme = themeMap[companyName] || themeMap.SprinklersNW;
|
const theme = themeMap[companyName] || themeMap["Sprinklers Northwest"];
|
||||||
this.currentTheme = theme;
|
this.currentTheme = theme;
|
||||||
if (typeof document === "undefined") return;
|
if (typeof document === "undefined") return;
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
@ -123,6 +128,7 @@ export const useThemeStore = defineStore("theme", {
|
||||||
root.style.setProperty("--theme-secondary-gradient-start", theme.secondaryGradientStart);
|
root.style.setProperty("--theme-secondary-gradient-start", theme.secondaryGradientStart);
|
||||||
root.style.setProperty("--theme-secondary-gradient-end", theme.secondaryGradientEnd);
|
root.style.setProperty("--theme-secondary-gradient-end", theme.secondaryGradientEnd);
|
||||||
root.style.setProperty("--theme-secondary-gradient", theme.secondaryGradient);
|
root.style.setProperty("--theme-secondary-gradient", theme.secondaryGradient);
|
||||||
|
root.style.setProperty("--theme-background-gradient", theme.backgroundGradient);
|
||||||
root.style.setProperty("--theme-surface", theme.surface);
|
root.style.setProperty("--theme-surface", theme.surface);
|
||||||
root.style.setProperty("--theme-surface-alt", theme.surfaceAlt);
|
root.style.setProperty("--theme-surface-alt", theme.surfaceAlt);
|
||||||
root.style.setProperty("--theme-border", theme.border);
|
root.style.setProperty("--theme-border", theme.border);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue