an updated and hopefully faster version of the ST Toolbox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

132 lines
4.9 KiB

{{define "users_content"}}
<div class="page-header">
<h2>User Imports</h2>
<p>Upload a CSV to create ServiceTrade users and assign roles in bulk.</p>
</div>
<div class="page-content">
<div class="content">
<h3 class="submenu-header">Upload CSV</h3>
{{if .FlashError}}
<div class="error-message">{{.FlashError}}</div>
{{end}}
{{if .FlashSuccess}}
<div class="info-message">{{.FlashSuccess}}</div>
{{end}}
<form action="/users/upload" method="POST" enctype="multipart/form-data">
{{if .CSRFField}}{{.CSRFField}}{{end}}
{{if .CSRFCookie}}<input type="hidden" name="csrfToken" value="{{.CSRFCookie}}">{{end}}
<label for="users-csv">CSV file</label>
<input id="users-csv" name="csvFile" type="file" accept=".csv" class="card-input" required>
<button type="submit" class="btn-primary">Process CSV</button>
</form>
<div class="info-message" style="margin-top: 1rem;">
<strong>Required headers:</strong> username, firstName, lastName, email, password, companyId, locationId.
Optional headers include phone, status, timezone, details, isSales, managerId, mfaRequired, serviceLineIds, and roles.
In the roles column list the human-readable role names (comma, semicolon, or pipe separated); names are matched case-insensitively.
</div>
</div>
{{if .RolesError}}
<div class="content" style="margin-top:1rem;">
<div class="error-message">{{.RolesError}}</div>
</div>
{{end}}
{{if .Roles}}
<div class="content" style="margin-top:1rem;">
<h3 class="submenu-header">Available Roles</h3>
<p>Use the role names from this list in the CSV roles column.</p>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Global</th>
</tr>
</thead>
<tbody>
{{range .Roles}}
<tr>
<td>{{.ID}}</td>
<td>{{.Name}}</td>
<td>{{.Description}}</td>
<td>{{if .Global}}Yes{{else}}No{{end}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{if .ImportSummary}}
<div class="content" style="margin-top:1rem;">
<h3 class="submenu-header">Import Summary</h3>
<p>
Processed file: <strong>{{.ImportSummary.ProcessedFilename}}</strong> at {{.ImportSummary.ProcessedAt.Format "2006-01-02 15:04 MST"}}.
</p>
<ul>
<li>Total rows: {{.ImportSummary.TotalRows}}</li>
<li>Users created: {{.ImportSummary.UsersCreated}}</li>
<li>Rows failed: {{.ImportSummary.RowsFailed}}</li>
<li>Role assignments succeeded: {{.ImportSummary.RoleAssignments}}</li>
<li>Role assignments failed: {{.ImportSummary.RoleAssignmentErrors}}</li>
</ul>
</div>
{{end}}
{{if .ImportResults}}
<div class="content" style="margin-top:1rem;">
<h3 class="submenu-header">Import Details</h3>
<table>
<thead>
<tr>
<th>Row</th>
<th>Username</th>
<th>Email</th>
<th>User Result</th>
<th>Role Assignments</th>
<th>Processing Time</th>
</tr>
</thead>
<tbody>
{{range .ImportResults}}
<tr>
<td>{{.Row}}</td>
<td>{{.Username}}</td>
<td>{{.Email}}</td>
<td>
{{if .Error}}
<div class="error-message">{{.Error}}</div>
{{else if .Created}}
Created (#{{.UserID}})
{{else}}
Skipped
{{end}}
</td>
<td>
{{if .RoleAssignments}}
<ul>
{{range .RoleAssignments}}
<li>
{{if .Success}}✅{{else}}⚠️{{end}}
{{if .Role}}{{.Role}} ({{.RoleID}}){{else}}{{.Token}}{{end}} &mdash; {{.Message}}
</li>
{{end}}
</ul>
{{else if .Error}}
&mdash;
{{else}}
No roles provided
{{end}}
</td>
<td>{{.ProcessingTime}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
</div>
{{end}}