Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2022 refactor - dash-salesforce-crm #717

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 191 additions & 6 deletions apps/dash-salesforce-crm/.gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,192 @@
venv/
.env
# .gitignore specifies the files that shouldn't be included
# in version control and therefore shouldn't be included when
# deploying an application to Dash Enterprise
# This is a very exhaustive list!
# This list was based off of https://github.com/github/gitignore

# Ignore data that is generated during the runtime of an application
# This folder is used by the "Large Data" sample applications
runtime_data/
data/

# Omit SQLite databases that may be produced by dash-snapshots in development
*.db

# Byte-compiled / optimized / DLL files
__pycache__/
apps/__pycache__/
*.DS_Store
.vscode
secrets.sh
*.py[cod]
*$py.class


# Jupyter Notebook

.ipynb_checkpoints
*/.ipynb_checkpoints/*

# IPython
profile_default/
ipython_config.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
secrets.sh

# Spyder project settings
.spyderproject
.spyproject

*.log
local_settings.py
db.sqlite3
db.sqlite3-journal


# macOS General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

# History files
.Rhistory
.Rapp.history

# Session Data files
.RData

# User-specific files
.Ruserdata

# Example code in package build process
*-Ex.R

# Output files from R CMD check
/*.Rcheck/

# RStudio files
.Rproj.user/

# produced vignettes
vignettes/*.html
vignettes/*.pdf

# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth

# knitr and R markdown default cache directories
*_cache/
/cache/

# Temporary files created by R markdown
*.utf8.md
*.knit.md

# R Environment Variables
.Renviron

# Linux
*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

# VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace

# SublineText
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache

# Workspace files are user-specific
*.sublime-workspace

# Project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using Sublime Text
# *.sublime-project

# SFTP configuration file
sftp-config.json

# Package control specific files
Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/
Package Control.merged-ca-bundle
Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache

# Sublime-github package stores a github token in this file
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings
2 changes: 1 addition & 1 deletion apps/dash-salesforce-crm/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn index:server
web: gunicorn app:server
8 changes: 4 additions & 4 deletions apps/dash-salesforce-crm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ This app uses Salesforce API in order to implement a custom CRM dashboard. The A

The following are screenshots for the app in this repo:

![Screenshot1](screenshots/opportunities_screenshot.png)
![Screenshot1](assets/github/opportunities_screenshot.png)

![Screenshot1](screenshots/leads_screenshot.png)
![Screenshot1](assets/github/leads_screenshot.png)

![Screenshot1](screenshots/cases_screenshot.png)
![Screenshot1](assets/github/cases_screenshot.png)

![Animated](screenshots/dash-salesforce-demo.gif)
![Animated](assets/github/dash-salesforce-demo.gif)



73 changes: 27 additions & 46 deletions apps/dash-salesforce-crm/app.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,31 @@
import math
import dash
import dash_html_components as html
from dash import Dash, html, dcc, Input, Output
import dash_bootstrap_components as dbc
from pages import opportunities, cases, leads

from sfManager import sf_Manager
from constants import salesforce_manager
from utils.components import Header

app = dash.Dash(
__name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}]
app = Dash(
__name__,
external_stylesheets=[dbc.themes.QUARTZ],
title="CRM Salesforce"
)
server = app.server

app.layout = dbc.Container([
Header(app),
dbc.Tabs([
dbc.Tab(opportunities.layout, label="Opportunities"),
dbc.Tab(leads.layout, label="Leads"),
dbc.Tab(cases.layout, label="Cases"),
]),

dcc.Store(id="opportunities_df", data=salesforce_manager.get_opportunities().to_json(orient="split")),
dcc.Store(id="leads_df", data=salesforce_manager.get_leads().to_json(orient="split")),
dcc.Store(id="cases_df", data=salesforce_manager.get_cases().to_json(orient="split")),
],
fluid=True,
)

app.config.suppress_callback_exceptions = True

sf_manager = sf_Manager()

millnames = ["", " K", " M", " B", " T"] # used to convert numbers


# return html Table with dataframe values
def df_to_table(df):
return html.Table(
[html.Tr([html.Th(col) for col in df.columns])]
+ [
html.Tr([html.Td(df.iloc[i][col]) for col in df.columns])
for i in range(len(df))
]
)


# returns most significant part of a number
def millify(n):
n = float(n)
millidx = max(
0,
min(
len(millnames) - 1, int(math.floor(0 if n == 0 else math.log10(abs(n)) / 3))
),
)

return "{:.0f}{}".format(n / 10 ** (3 * millidx), millnames[millidx])


# returns top indicator div
def indicator(color, text, id_value):
return html.Div(
[
html.P(id=id_value, className="indicator_value"),
html.P(text, className="twelve columns indicator_text"),
],
className="four columns indicator pretty_container",
)
if __name__ == "__main__":
app.run_server(debug=True)
83 changes: 83 additions & 0 deletions apps/dash-salesforce-crm/assets/css/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
.header {
padding: 5px 15px 5px 10px;
}

.header-logos {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
gap: 5%;
}

.row {
margin-top: 20px;
}

.card {
margin-bottom: 20px;
}

.tab-content {
padding: 10px 10rem 0 10rem;
}

/* graph background color */
.main-svg {
background-color: transparent !important;
}
.layer.bg * {
fill: none !important;
}
/* Graph legend */
.infolayer .legend .bg {
fill: none !important;
}

/* table */
td {
background-color: transparent !important;
}
th span {
font-weight: bold;
text-align: center;
}
th {
background-color: rgba(202, 65, 123, 0.7) !important;
}


/* Demo button css */
.demo-button {
font-family: Open Sans,sans-serif;
text-decoration: none;
display: inline-flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-radius: 8px;
font-weight: 700;
height: 2.5rem;
font-size: 13px;
-webkit-padding-start: 1rem;
padding-inline-start: 1rem;
-webkit-padding-end: 1rem;
padding-inline-end: 1rem;
color: #ffffff;
letter-spacing: 2px;
border: solid 1.5px transparent;
box-shadow: 2px 1000px 1px #0c0c0c inset;
background-image: linear-gradient(135deg, #7A76FF, #7A76FF, #7FE4FF);
-webkit-background-size: 200% 100%;
background-size: 200% 100%;
-webkit-background-position: 99%;
background-position: 99%;
background-origin: border-box;
transition: all .4s ease-in-out;
padding-top: 15px;
padding-bottom: 15px;
}
.demo-button:hover {
color: #7A76FF;
}
Loading