Commit 99843e78 authored by Lee Brown's avatar Lee Brown

completed project section

parent d574f8e2
This diff is collapsed.
......@@ -43,8 +43,15 @@ func APP(shutdown chan os.Signal, log *log.Logger, env webcontext.Env, staticDir
// Register project management pages.
p := Projects{
MasterDB: masterDB,
Redis: redis,
Renderer: renderer,
}
app.Handle("POST", "/projects/:project_id/update", p.Update, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/projects/:project_id/update", p.Update, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("POST", "/projects/:project_id", p.View, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/projects/:project_id", p.View, mid.AuthenticateSessionRequired(authenticator), mid.HasAuth())
app.Handle("POST", "/projects/create", p.Create, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/projects/create", p.Create, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/projects", p.Index, mid.AuthenticateSessionRequired(authenticator), mid.HasAuth())
// Register user management pages.
......@@ -63,7 +70,7 @@ func APP(shutdown chan os.Signal, log *log.Logger, env webcontext.Env, staticDir
app.Handle("GET", "/users/:user_id", us.View, mid.AuthenticateSessionRequired(authenticator), mid.HasAuth())
app.Handle("POST", "/users/create", us.Create, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/users/create", us.Create, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/users", us.Index, mid.AuthenticateSessionRequired(authenticator), mid.HasRole(auth.RoleAdmin))
app.Handle("GET", "/users", us.Index, mid.AuthenticateSessionRequired(authenticator), mid.HasAuth())
// Register user management and authentication endpoints.
u := User{
......
{{define "title"}}Create Project{{end}}
{{define "style"}}
{{end}}
{{define "content"}}
<form class="user" method="post" novalidate>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="inputName">Name</label>
<input type="text" class="form-control {{ ValidationFieldClass $.validationErrors "Name" }}"
placeholder="enter name" name="Name" id="inputName" value="{{ .form.Name }}" required>
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Name" }}
</div>
</div>
</div>
<div class="spacer-30"></div>
<div class="row">
<div class="col">
<input id="btnSubmit" type="submit" name="action" value="Save" class="btn btn-primary"/>
</div>
</div>
</form>
{{end}}
{{define "js"}}
{{end}}
{{define "title"}}Projects{{end}}
{{define "content"}}
{{ if HasRole $._Ctx "admin" }}
<a href="{{ .urlProjectsCreate }}">Create Project</a>
{{ end }}
<div class="row">
<div class="col">
<form method="post">
<div class="card">
<div class="table-responsive dataTable_card">
{{ template "partials/datatable/html" . }}
</div>
</div>
</form>
</div>
</div>
{{end}}
{{define "style"}}
{{ template "partials/datatable/style" . }}
{{ end }}
{{define "js"}}
{{ template "partials/datatable/js" . }}
<script>
$(document).ready(function(){
//$("#dataTable_filter").hide();
});
</script>
{{end}}
{{define "title"}}Update Project - {{ .project.Name }}{{end}}
{{define "style"}}
{{end}}
{{define "content"}}
<form class="user" method="post" novalidate>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="inputName">Name</label>
<input type="text" class="form-control {{ ValidationFieldClass $.validationErrors "Name" }}"
placeholder="enter name" name="Name" id="inputName" value="{{ .form.Name }}" required>
{{template "invalid-feedback" dict "validationDefaults" $.userValidationDefaults "validationErrors" $.validationErrors "fieldName" "Name" }}
</div>
<div class="form-group">
<label for="selectStatus">Status</label>
<select class="form-control {{ ValidationFieldClass $.validationErrors "Status" }}"
id="selectStatus" name="Status">
{{ range $idx, $t := .project.Status.Options }}
<option value="{{ $t.Value }}" {{ if $t.Selected }}selected="selected"{{ end }}>{{ $t.Title }}</option>
{{ end }}
</select>
{{template "invalid-feedback" dict "validationDefaults" $.validationDefaults "validationErrors" $.validationErrors "fieldName" "Status" }}
</div>
</div>
</div>
<div class="spacer-30"></div>
<div class="row">
<div class="col">
<input id="btnSubmit" type="submit" name="action" value="Save" class="btn btn-primary"/>
</div>
</div>
</form>
{{end}}
{{define "js"}}
{{end}}
{{define "title"}}Project - {{ .project.Name }}{{end}}
{{define "style"}}
{{end}}
{{define "content"}}
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<h4>Name</h4>
<p class="font-14">
{{ .project.Name }}
</p>
</div>
</div>
</div>
<div class="col-auto">
<a href="{{ .urlProjectsUpdate }}" class="btn btn-outline-success"><i class="fal fa-edit"></i>Edit Details</a>
{{ if HasRole $._Ctx "admin" }}
<form method="post"><input type="hidden" name="action" value="archive" /><input type="submit" value="Archive"></form>
{{ end }}
</div>
</div>
<div class="spacer-30"></div>
<div class="row">
<div class="col-md-6">
<p>
<small>Name</small><br/>
<b>{{ .project.Name }}</b>
</p>
<div class="spacer-15"></div>
</div>
<div class="col-md-6">
<p>
<small>Status</small><br/>
{{ if .project }}
<b>
{{ if eq .project.Status.Value "active" }}
<span class="text-green"><i class="fas fa-circle"></i>{{ .project.Status.Title }}</span>
{{else}}
<span class="text-orange"><i class="far fa-circle"></i>{{.project.Status.Title }}</span>
{{end}}
</b>
{{ end }}
</p>
<p>
<small>ID</small><br/>
<b>{{ .project.ID }}</b>
</p>
</div>
</div>
{{end}}
{{define "js"}}
{{end}}
{{define "title"}}Users{{end}}
{{define "content"}}
<a href="{{ .urlUsersCreate }}">Create User</a>
{{ if HasRole $._Ctx "admin" }}
<a href="{{ .urlUsersCreate }}">Create User</a>
{{ end }}
<div class="row">
<div class="col">
<form method="post">
......
{{define "title"}}Update Profile{{end}}
{{define "title"}}Update User - {{ .user.Name }}{{end}}
{{define "style"}}
{{end}}
......
{{define "title"}}Profile{{end}}
{{define "title"}}User - {{ .user.Name }}{{end}}
{{define "style"}}
{{end}}
......@@ -16,15 +16,15 @@
</p>
</div>
</div>
<div class="spacer-10"></div>
<p class="font-10"><a href="https://gravatar.com" target="_blank">Update Avatar</a></p>
</div>
<div class="col-auto">
<a href="{{ .urlUsersUpdate }}" class="btn btn-outline-success"><i class="fal fa-edit"></i>Edit Details</a>
{{ $ctxUser := ContextUser $._Ctx }}
{{ if $ctxUser }}
{{ if ne .user.ID $ctxUser.ID }}
<form method="post"><input type="hidden" name="action" value="archive" /><input type="submit" value="Archive"></form>
{{ if HasRole $._Ctx "admin" }}
<a href="{{ .urlUsersUpdate }}" class="btn btn-outline-success"><i class="fal fa-edit"></i>Edit Details</a>
{{ $ctxUser := ContextUser $._Ctx }}
{{ if $ctxUser }}
{{ if ne .user.ID $ctxUser.ID }}
<form method="post"><input type="hidden" name="action" value="archive" /><input type="submit" value="Archive"></form>
{{ end }}
{{ end }}
{{ end }}
</div>
......
......@@ -38,8 +38,7 @@
</a>
<div id="navSectionProjects" class="collapse" data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item" href="buttons.html">Buttons</a>
<a class="collapse-item" href="cards.html">Cards</a>
<a class="collapse-item" href="/projects">Projects</a>
</div>
</div>
</li>
......
......@@ -25,11 +25,11 @@
<ul class="navbar-nav ml-auto">
<!-- Nav Item - Search Dropdown (Visible Only XS) -->
<li class="nav-item dropdown no-arrow d-sm-none">
<!-- li class="nav-item dropdown no-arrow d-sm-none">
<a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-search fa-fw"></i>
</a>
<!-- Dropdown - Messages -->
< ! -- Dropdown - Messages -- >
<div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown">
<form class="form-inline mr-auto w-100 navbar-search">
<div class="input-group">
......@@ -42,16 +42,16 @@
</div>
</form>
</div>
</li>
</li -->
<!-- Nav Item - Alerts -->
<li class="nav-item dropdown no-arrow mx-1">
<!-- li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" href="#" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-bell fa-fw"></i>
<!-- Counter - Alerts -->
< !-- Counter - Alerts -- >
<span class="badge badge-danger badge-counter">3+</span>
</a>
<!-- Dropdown - Alerts -->
< !-- Dropdown - Alerts -- >
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown">
<h6 class="dropdown-header">
Alerts Center
......@@ -91,16 +91,16 @@
</a>
<a class="dropdown-item text-center small text-gray-500" href="#">Show All Alerts</a>
</div>
</li>
</li -->
<!-- Nav Item - Messages -->
<li class="nav-item dropdown no-arrow mx-1">
<!-- li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" href="#" id="messagesDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-envelope fa-fw"></i>
<!-- Counter - Messages -->
< !-- Counter - Messages -- >
<span class="badge badge-danger badge-counter">7</span>
</a>
<!-- Dropdown - Messages -->
< !-- Dropdown - Messages -- >
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="messagesDropdown">
<h6 class="dropdown-header">
Message Center
......@@ -147,7 +147,7 @@
</a>
<a class="dropdown-item text-center small text-gray-500" href="#">Read More Messages</a>
</div>
</li>
</li -->
<div class="topbar-divider d-none d-sm-block"></div>
......
......@@ -40,7 +40,7 @@ func (m *AccountPreference) Response(ctx context.Context) *AccountPreferenceResp
r := &AccountPreferenceResponse{
AccountID: m.AccountID,
Name: web.NewEnumResponse(ctx, m.Name, AccountPreferenceName_Values),
Name: web.NewEnumResponse(ctx, m.Name, AccountPreferenceName_ValuesInterface()...),
Value: m.Value,
CreatedAt: web.NewTimeResponse(ctx, m.CreatedAt),
UpdatedAt: web.NewTimeResponse(ctx, m.UpdatedAt),
......@@ -122,6 +122,15 @@ var AccountPreferenceName_Values = []AccountPreferenceName{
AccountPreference_Time_Format,
}
// AccountPreferenceName_ValuesInterface returns the AccountPreferenceName options as a slice interface.
func AccountPreferenceName_ValuesInterface() []interface{} {
var l []interface{}
for _, v := range AccountPreferenceName_Values {
l = append(l, v.String())
}
return l
}
// Scan supports reading the AccountPreferenceName value from the database.
func (s *AccountPreferenceName) Scan(value interface{}) error {
asBytes, ok := value.(string)
......
......@@ -68,7 +68,7 @@ func (m *Account) Response(ctx context.Context) *AccountResponse {
Country: m.Country,
Zipcode: m.Zipcode,
Timezone: m.Timezone,
Status: web.NewEnumResponse(ctx, m.Status, AccountStatus_Values),
Status: web.NewEnumResponse(ctx, m.Status, AccountStatus_ValuesInterface()...),
CreatedAt: web.NewTimeResponse(ctx, m.CreatedAt),
UpdatedAt: web.NewTimeResponse(ctx, m.UpdatedAt),
}
......@@ -200,6 +200,15 @@ var AccountStatus_Values = []AccountStatus{
AccountStatus_Disabled,
}
// AccountStatus_ValuesInterface returns the AccountStatus options as a slice interface.
func AccountStatus_ValuesInterface() []interface{} {
var l []interface{}
for _, v := range AccountStatus_Values {
l = append(l, v.String())
}
return l
}
// Scan supports reading the AccountStatus value from the database.
func (s *AccountStatus) Scan(value interface{}) error {
asBytes, ok := value.([]byte)
......
......@@ -101,11 +101,16 @@ func NewEnumResponse(ctx context.Context, value interface{}, options ...interfac
for _, opt := range options {
optStr := fmt.Sprintf("%s", opt)
er.Options = append(er.Options, EnumOption{
Value: optStr,
Title: EnumValueTitle(optStr),
Selected: (value == opt),
})
opt := EnumOption{
Value: optStr,
Title: EnumValueTitle(optStr),
}
if optStr == er.Value {
opt.Selected = true
}
er.Options = append(er.Options, opt)
}
return er
......
......@@ -43,7 +43,7 @@ func (m *Project) Response(ctx context.Context) *ProjectResponse {
ID: m.ID,
AccountID: m.AccountID,
Name: m.Name,
Status: web.NewEnumResponse(ctx, m.Status, ProjectStatus_Values),
Status: web.NewEnumResponse(ctx, m.Status, ProjectStatus_ValuesInterface()...),
CreatedAt: web.NewTimeResponse(ctx, m.CreatedAt),
UpdatedAt: web.NewTimeResponse(ctx, m.UpdatedAt),
}
......@@ -133,6 +133,15 @@ var ProjectStatus_Values = []ProjectStatus{
ProjectStatus_Disabled,
}
// ProjectStatus_ValuesInterface returns the ProjectStatus options as a slice interface.
func ProjectStatus_ValuesInterface() []interface{} {
var l []interface{}
for _, v := range ProjectStatus_Values {
l = append(l, v.String())
}
return l
}
// Scan supports reading the ProjectStatus value from the database.
func (s *ProjectStatus) Scan(value interface{}) error {
asBytes, ok := value.([]byte)
......
......@@ -53,7 +53,7 @@ func (m *UserAccount) Response(ctx context.Context) *UserAccountResponse {
UserID: m.UserID,
AccountID: m.AccountID,
Roles: m.Roles,
Status: web.NewEnumResponse(ctx, m.Status, UserAccountStatus_Values),
Status: web.NewEnumResponse(ctx, m.Status, UserAccountStatus_ValuesInterface()...),
CreatedAt: web.NewTimeResponse(ctx, m.CreatedAt),
UpdatedAt: web.NewTimeResponse(ctx, m.UpdatedAt),
}
......@@ -169,6 +169,15 @@ var UserAccountStatus_Values = []UserAccountStatus{
UserAccountStatus_Disabled,
}
// UserAccountStatus_ValuesInterface returns the UserAccountStatus options as a slice interface.
func UserAccountStatus_ValuesInterface() []interface{} {
var l []interface{}
for _, v := range UserAccountStatus_Values {
l = append(l, v.String())
}
return l
}
// Scan supports reading the UserAccountStatus value from the database.
func (s *UserAccountStatus) Scan(value interface{}) error {
asBytes, ok := value.([]byte)
......@@ -217,6 +226,15 @@ var UserAccountRole_Values = []UserAccountRole{
UserAccountRole_User,
}
// UserAccountRole_ValuesInterface returns the UserAccountRole options as a slice interface.
func UserAccountRole_ValuesInterface() []interface{} {
var l []interface{}
for _, v := range UserAccountRole_Values {
l = append(l, v.String())
}
return l
}
// String converts the UserAccountRole value to a string.
func (s UserAccountRole) String() string {
return string(s)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment