/
st-sales-reps-dashboard.Rmd
227 lines (155 loc) · 5.87 KB
/
st-sales-reps-dashboard.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
---
title: "Tutorial: Full dashboard UI in Shiny and Fluent"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Tutorial: Full dashboard UI in Shiny and Fluent}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r setup}
library(shiny.fluent)
```
```{r, include=FALSE, cache=FALSE}
do.call(knitr::read_chunk, list(path = "../inst/examples/tutorial/dashboard_layout.R"))
```
This is Part 2 of shiny.fluent tutorial.
In [Part 1](../articles/shiny-fluent.html) we built a pretty functional app, but honestly, it doesn't look particularly great. Let's now build a good looking dashboard UI for that app. It will have a top command bar with a title, a sidebar with navigation, and multiple pages handled by router.
# Prerequisites
We are starting with the [code Part 1 ends with](https://appsilon.github.io/shiny.fluent/articles/shiny-fluent.html).
Let's start by changing the beginning of our file to load all libraries that we will use in this example. Make sure to install the ones you don't have yet installed (if any).
```{r libraries, eval=FALSE}
```
# Single page layout
As a next step, let's add a title and subtitle to our current app. We'll create a helper function and call it `makePage`, so that it is easy to add more pages in the same fashion.
```{r make-page, eval=FALSE}
```
We can now take our entire UI built so far and put it in a "page" layout, giving it a helpful title and subtitle.
```{r analysis-page, eval=FALSE}
```
```{r, echo=FALSE}
knitr::include_graphics("images/tutorial-part2-step1.png")
```
# Dashboard Layout
It's time to create a place for our header, navigation sidebar and footer. We'll use CSS grid for that. It's a modern, flexible and staightforward way to achieve such a layout.
We start by creating divs for each of the areas, with placeholder texts that we will later replace.
```{r layout, eval=FALSE}
```
Now it's time to tell the browser using CSS how to arrange these areas. To define how our areas should be laid out on the page, let's put the following rules in `www/style.css`:
```css
.grid-container {
display: grid;
grid-template-columns: 320px 1fr;
grid-template-rows: 54px 1fr 45px;
grid-template-areas: "header header" "sidenav main" "footer footer";
height: 100vh;
}
.header {
grid-area: header;
background-color: #fff;
padding: 6px 0px 6px 10px;
display: flex;
}
.main {
grid-area: main;
background-color: #faf9f8;
padding-left: 40px;
padding-right: 32px;
max-width: calc(100vw - 400px);
max-height: calc(100vh - 100px);
overflow: auto;
}
.footer {
grid-area: footer;
background-color: #f3f2f1;
padding: 12px 20px;
}
.sidenav {
grid-area: sidenav;
background-color: #fff;
padding: 25px;
}
```
We can also use this opportunity to add some additional styling for the entire page, and add the following rules to the same file:
```css
body {
background-color: rgba(225, 223, 221, 0.2);
min-height: 611px;
margin: 0;
}
.page-title {
padding: 52px 0px;
}
.card {
background: #fff;
padding: 28px;
margin-bottom: 28px;
border-radius: 2px;
background-clip: padding-box;
}
```
Now we only need to update our UI definition to load styles from `www/style.css` and use the new layout.
```{r basic-layout-ui, eval=FALSE}
```
```{r, echo=FALSE}
knitr::include_graphics("images/tutorial-part2-step2.png")
```
# Filling all the areas
Great! Now it's time to fill those areas with something. We can start with the header.
## Header
Let's replace the previous header definition with:
```{r header, eval=FALSE}
```
As you can see, we're using `CommandBar` and `CommandBarItem` from shiny.fluent. We also need to add a bit of styling to our CSS file:
```css
.title {
padding: 0px 14px 0px 14px;
color: #737373;
margin: 6px 0px 6px 10px;
border-left: 1px solid darkgray;
width: 220px;
}
.logo {
height: 44px;
}
```
## Navigation in the sidebar
`Nav` is a very powerful component from Fluent UI. It has very rich configuration options, but we will use it to show just a couple of links:
```{r navigation, eval=FALSE}
```
## Footer
Footer is relatively straightforward - we can put anything we want there. Here we use `Text` for typography (setting uniform font styling). We also use `Stack` to arrange elements horizontally and with bigger gaps.
```{r footer, eval=FALSE}
```
Let's see how this looks together.
```{r, echo=FALSE}
knitr::include_graphics("images/tutorial-part2-step3.png")
```
# Additional pages
## Home page
The one final step is to add additional pages. Let's make a home page, consisting of two cards with some welcome text.
```{r home-page, eval=FALSE}
```
If we replace `analysis_page` with `home_page` in our `ui`, we can even see this page. However, there's one problem: we don't have a way to switch between pages! This is where so-called page routing comes into play.
## Adding shiny.router
To enable switching between pages we will use the [shiny.router](https://appsilon.github.io/shiny.router/) package. This way we will also have shareable URLs to individual pages.
The first step is to define the available routes:
```{r router, eval=FALSE}
```
Now, we need to put `router$ui` in the place where we want the selected page to appear. (Currently, we also need to manually include router's JavaScript dependencies, because `shiny.fluent` is not compatible with the way `shiny.router` loads this dependency. We expect this to be resolved in future versions of `shiny.router`).
```{r router-ui, eval=FALSE}
```
One final step is to add this single line to our `server` function, which otherwise remains untouched from the Part 1 of the tutorial.
```{r router-server, eval=FALSE}
```
# That's it!
That's it - we have styled a shiny.fluent app into a solid dashboard layout!
Here's the final result:
```{r, echo=FALSE}
knitr::include_graphics("images/tutorial-part2-final.gif")
```