add more info to getUsers, move admin.html css to scss files

more deatils included in getUsers response in prep for feature request #5. bs4 and bs5 css are now compiled instead of being copied.
This commit is contained in:
Harvey Tindall
2020-09-16 21:42:22 +01:00
parent 7d84fdec96
commit a8b4842895
12 changed files with 174 additions and 126 deletions
+27 -2
View File
@@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@@ -458,13 +459,29 @@ func (app *appContext) DeleteInvite(gc *gin.Context) {
respond(401, "Code doesn't exist", gc) respond(401, "Code doesn't exist", gc)
} }
type userResp struct { type dateToParse struct {
UserList []respUser `json:"users"` Parsed time.Time `json:"parseme"`
}
// json magically parses datetimes so why not
func parseDt(date string) time.Time {
timeJSON := []byte("{ \"parseme\": \"" + date + "\" }")
var parsed dateToParse
json.Unmarshal(timeJSON, &parsed)
return parsed.Parsed
} }
type respUser struct { type respUser struct {
ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Email string `json:"email,omitempty"` Email string `json:"email,omitempty"`
// this magically parses a string to time.time
LastActive string `json:"last_active"`
Admin bool `json:"admin"`
}
type userResp struct {
UserList []respUser `json:"users"`
} }
func (app *appContext) GetUsers(gc *gin.Context) { func (app *appContext) GetUsers(gc *gin.Context) {
@@ -480,10 +497,18 @@ func (app *appContext) GetUsers(gc *gin.Context) {
} }
for _, jfUser := range users { for _, jfUser := range users {
var user respUser var user respUser
user.LastActive = "n/a"
if jfUser["LastActivityDate"] != nil {
date := parseDt(jfUser["LastActivityDate"].(string))
user.LastActive = app.formatDatetime(date)
}
user.ID = jfUser["Id"].(string)
user.Name = jfUser["Name"].(string) user.Name = jfUser["Name"].(string)
user.Admin = jfUser["Policy"].(map[string]interface{})["IsAdministrator"].(bool)
if email, ok := app.storage.emails[jfUser["Id"].(string)]; ok { if email, ok := app.storage.emails[jfUser["Id"].(string)]; ok {
user.Email = email.(string) user.Email = email.(string)
} }
resp.UserList = append(resp.UserList, user) resp.UserList = append(resp.UserList, user)
} }
gc.JSON(200, resp) gc.JSON(200, resp)
File diff suppressed because one or more lines are too long
+1 -2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -2
View File
File diff suppressed because one or more lines are too long
+1 -79
View File
@@ -65,82 +65,6 @@
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
{{ end }} {{ end }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.pageContainer {
margin: 5% 20% 5% 20%;
}
@media (max-width: 1100px) {
.pageContainer {
margin: 2%;
}
}
h1 {
/*margin: 20%;*/
margin-bottom: 5%;
}
.linkGroup {
/*margin: 20%;*/
margin-bottom: 5%;
margin-top: 5%;
}
.linkForm {
/*margin: 20%;*/
margin-top: 5%;
margin-bottom: 5%;
}
.contactBox {
/*margin: 20%;*/
margin-top: 5%;
color: grey;
}
.circle {
/*margin-left: 1rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
z-index: 5000;*/
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeInCubic */
}
.smooth-transition {
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeincubic */
}
.rotated {
transform: rotate(180deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
}
.not-rotated {
transform: rotate(0deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
}
.invite-link {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: auto;
}
.settingIcon {
margin-left: 0.2rem;
}
body.modal-open {
overflow: hidden;
}
</style>
<title>Admin</title> <title>Admin</title>
</head> </head>
<body class="smooth-transition"> <body class="smooth-transition">
@@ -316,9 +240,7 @@
</div> </div>
</div> </div>
<div class="pageContainer"> <div class="pageContainer">
<h1> <h1><a class="text-button">Invites </a></h1>
Accounts admin
</h1>
<div class="btn-group" role="group" id="headerButtons"> <div class="btn-group" role="group" id="headerButtons">
<button type="button" class="btn btn-primary" id="openSettings"> <button type="button" class="btn btn-primary" id="openSettings">
Settings <i class="fa fa-cog"></i> Settings <i class="fa fa-cog"></i>
+96
View File
@@ -0,0 +1,96 @@
.pageContainer {
margin: 5% 20% 5% 20%;
}
@media (max-width: 1100px) {
.pageContainer {
margin: 2%;
}
}
h1 {
/*margin: 20%;*/
margin-bottom: 5%;
}
.linkGroup {
/*margin: 20%;*/
margin-bottom: 5%;
margin-top: 5%;
}
.linkForm {
/*margin: 20%;*/
margin-top: 5%;
margin-bottom: 5%;
}
.contactBox {
/*margin: 20%;*/
margin-top: 5%;
color: grey;
}
.circle {
/*margin-left: 1rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
z-index: 5000;*/
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeInCubic */
}
.smooth-transition {
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeincubic */
}
.rotated {
transform: rotate(180deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
}
.not-rotated {
transform: rotate(0deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
}
.invite-link {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: auto;
}
.settingIcon {
margin-left: 0.2rem;
}
body.modal-open {
overflow: hidden;
}
@mixin scut-link-unstyled {
&, &:visited, &:hover, &:active {
font-style: inherit;
color: inherit;
background-color: transparent;
font-size: inherit;
text-decoration: none;
font-variant: inherit;
font-weight: inherit;
line-height: inherit;
font-family: inherit;
}
}
%scut-link-unstyled {
@include scut-link-unstyled;
}
.text-button {
@extend %scut-link-unstyled;
}
+1
View File
@@ -138,3 +138,4 @@ $list-group-action-active-bg: $jf-blue-focus;
background-color: $success; background-color: $success;
} }
@import "../base.scss";
+2
View File
@@ -0,0 +1,2 @@
@import "../../node_modules/bootstrap4/scss/bootstrap";
@import "../base.scss";
+1
View File
@@ -138,3 +138,4 @@ $list-group-action-active-bg: $jf-blue-focus;
background-color: $success; background-color: $success;
} }
@import "../base.scss";
+2
View File
@@ -0,0 +1,2 @@
@import "../../node_modules/bootstrap/scss/bootstrap";
@import "../base.scss";
+29 -28
View File
@@ -39,44 +39,45 @@ if not args.yes:
node_bin = input("input bin directory: ") node_bin = input("input bin directory: ")
for bsv in [d for d in local_path.iterdir() if "bs" in d.name]: for bsv in [d for d in local_path.iterdir() if "bs" in d.name]:
scss = bsv / f"{bsv.name}-jf.scss" scss = [(bsv / f"{bsv.name}-jf.scss"), (bsv / f"{bsv.name}.scss")]
css = bsv / f"{bsv.name}-jf.css" css = [(bsv / f"{bsv.name}-jf.css"), (bsv / f"{bsv.name}.css")]
min_css = bsv.parents[1] / "data" / "static" / f"{bsv.name}-jf.css" min_css = [(bsv.parents[1] / "data" / "static" / f"{bsv.name}-jf.css"), (bsv.parents[1] / "data" / "static" / f"{bsv.name}.css")]
with open(css, "w") as f: for i in range(2):
with open(css[i], "w") as f:
f.write( f.write(
sass.compile( sass.compile(
filename=str(scss.resolve()), output_style="expanded", precision=6 filename=str(scss[i].resolve()), output_style="expanded", precision=6
) )
) )
if css.exists(): if css[i].exists():
print(f"{bsv.name}: Compiled.") print(f"{scss[i].name}: Compiled.")
# postcss only excepts forwards slashes? weird. # postcss only excepts forwards slashes? weird.
cssPath = str(css.resolve()) cssPath = str(css[i].resolve())
if os.name == "nt": if os.name == "nt":
cssPath = cssPath.replace("\\", "/") cssPath = cssPath.replace("\\", "/")
runcmd( runcmd(
f'{str((node_bin / "postcss").resolve())} {cssPath} --replace --use autoprefixer' f'{str((node_bin / "postcss").resolve())} {cssPath} --replace --use autoprefixer'
) )
print(f"{bsv.name}: Prefixed.") print(f"{scss[i].name}: Prefixed.")
runcmd( runcmd(
f'{str((node_bin / "cleancss").resolve())} --level 1 --format breakWith=lf --output {str(min_css.resolve())} {str(css.resolve())}' f'{str((node_bin / "cleancss").resolve())} --level 1 --format breakWith=lf --output {str(min_css[i].resolve())} {str(css[i].resolve())}'
) )
if min_css.exists(): if min_css[i].exists():
print(f"{bsv.name}: Minified and copied to {str(min_css.resolve())}.") print(f"{scss[i].name}: Minified and copied to {str(min_css[i].resolve())}.")
for v in [("bootstrap", "bs5"), ("bootstrap4", "bs4")]: # for v in [("bootstrap", "bs5"), ("bootstrap4", "bs4")]:
new_path = str((local_path.parent / "data" / "static" / (v[1] + ".css")).resolve()) # new_path = str((local_path.parent / "data" / "static" / (v[1] + ".css")).resolve())
shutil.copy( # shutil.copy(
str( # str(
( # (
local_path.parent # local_path.parent
/ "node_modules" # / "node_modules"
/ v[0] # / v[0]
/ "dist" # / "dist"
/ "css" # / "css"
/ "bootstrap.min.css" # / "bootstrap.min.css"
).resolve() # ).resolve()
), # ),
new_path, # new_path,
) # )
print(f"Copied {v[1]} to {new_path}") # print(f"Copied {v[1]} to {new_path}")