Add optional label for invites

Requested in #38.
This commit is contained in:
Harvey Tindall 2021-01-24 15:55:45 +00:00
parent ea262ca60b
commit dd96d71280
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
8 changed files with 51 additions and 17 deletions

4
api.go
View File

@ -532,6 +532,9 @@ func (app *appContext) GenerateInvite(gc *gin.Context) {
_, err = strconv.Atoi(string(inviteCode[0]))
}
var invite Invite
if req.Label != "" {
invite.Label = req.Label
}
invite.Created = currentTime
if req.MultipleUses {
if req.NoLimit {
@ -732,6 +735,7 @@ func (app *appContext) GetInvites(gc *gin.Context) {
Created: app.formatDatetime(inv.Created),
Profile: inv.Profile,
NoLimit: inv.NoLimit,
Label: inv.Label,
}
if len(inv.UsedBy) != 0 {
invite.UsedBy = inv.UsedBy

View File

@ -200,7 +200,7 @@ sup.\~critical, .text-critical {
max-width: 40%;
min-width: 10rem;
display: flex;
justify-content: center;
justify-content: start;
align-items: center;
}

View File

@ -219,12 +219,14 @@
<option>0</option>
</select>
</div>
<label class="label supra" for="create-label"> {{ .strings.label }}</label>
<input type="text" id="create-label" class="input ~neutral !normal mb-1 mt-half">
</div>
<div class="card ~neutral !normal col">
<label class="label supra" for="create-uses">{{ .strings.inviteNumberOfUses }}</label>
<div class="flex-expand mb-1 mt-half">
<input type="number" min="0" id="create-uses" class="input ~neutral !normal mr-1" value=1>
<label for="create-inf-uses" class="button ~neutral !normal">
<label for="create-inf-uses" class="button ~neutral !normal" title="Set uses to infinite">
<span></span>
<input type="checkbox" class="unfocused" id="create-inf-uses" aria-label="Set uses to infinite">
</label>

View File

@ -36,6 +36,7 @@
"success": "Success",
"error": "Error",
"unknown": "Unknown",
"label": "Label",
"modifySettings": "Modify Settings",
"modifySettingsDescription": "Apply settings from an existing profile, or source them directly from a user.",
"applyHomescreenLayout": "Apply homescreen layout",

View File

@ -38,6 +38,7 @@ type generateInviteDTO struct {
NoLimit bool `json:"no-limit" example:"false"` // No invite use limit
RemainingUses int `json:"remaining-uses" example:"5"` // Remaining invite uses
Profile string `json:"profile" example:"DefaultProfile"` // Name of profile to apply on this invite
Label string `json:"label" example:"For Friends"` // Optional label for the invite
}
type inviteProfileDTO struct {
@ -67,18 +68,19 @@ type newProfileDTO struct {
}
type inviteDTO struct {
Code string `json:"code" example:"sajdlj23423j23"` // Invite code
Days int `json:"days" example:"1"` // Number of days till expiry
Hours int `json:"hours" example:"2"` // Number of hours till expiry
Minutes int `json:"minutes" example:"3"` // Number of minutes till expiry
Created string `json:"created" example:"01/01/20 12:00"` // Date of creation
Profile string `json:"profile" example:"DefaultProfile"` // Profile used on this invite
UsedBy [][]string `json:"used-by,omitempty"` // Users who have used this invite
NoLimit bool `json:"no-limit,omitempty"` // If true, invite can be used any number of times
RemainingUses int `json:"remaining-uses,omitempty"` // Remaining number of uses (if applicable)
Email string `json:"email,omitempty"` // Email the invite was sent to (if applicable)
NotifyExpiry bool `json:"notify-expiry,omitempty"` // Whether to notify the requesting user of expiry or not
NotifyCreation bool `json:"notify-creation,omitempty"` // Whether to notify the requesting user of account creation or not
Code string `json:"code" example:"sajdlj23423j23"` // Invite code
Days int `json:"days" example:"1"` // Number of days till expiry
Hours int `json:"hours" example:"2"` // Number of hours till expiry
Minutes int `json:"minutes" example:"3"` // Number of minutes till expiry
Created string `json:"created" example:"01/01/20 12:00"` // Date of creation
Profile string `json:"profile" example:"DefaultProfile"` // Profile used on this invite
UsedBy [][]string `json:"used-by,omitempty"` // Users who have used this invite
NoLimit bool `json:"no-limit,omitempty"` // If true, invite can be used any number of times
RemainingUses int `json:"remaining-uses,omitempty"` // Remaining number of uses (if applicable)
Email string `json:"email,omitempty"` // Email the invite was sent to (if applicable)
NotifyExpiry bool `json:"notify-expiry,omitempty"` // Whether to notify the requesting user of expiry or not
NotifyCreation bool `json:"notify-creation,omitempty"` // Whether to notify the requesting user of account creation or not
Label string `json:"label,omitempty" example:"For Friends"` // Optional label for the invite
}
type getInvitesDTO struct {

View File

@ -41,6 +41,7 @@ type Invite struct {
UsedBy [][]string `json:"used-by"`
Notify map[string]map[string]bool `json:"notify"`
Profile string `json:"profile"`
Label string `json:"label,omitempty"`
}
type Lang struct {

View File

@ -25,7 +25,18 @@ export class DOMInvite implements Invite {
document.dispatchEvent(inviteDeletedEvent);
}
})
private _label: string = "";
get label(): string { return this._label; }
set label(label: string) {
this._label = label;
const linkEl = this._codeArea.querySelector("a") as HTMLAnchorElement;
if (label == "") {
linkEl.textContent = this.code.replace(/-/g, '-');
} else {
linkEl.textContent = label;
}
}
private _code: string = "None";
get code(): string { return this._code; }
set code(code: string) {
@ -36,7 +47,9 @@ export class DOMInvite implements Invite {
}
this._codeLink = codeLink + "invite/" + code;
const linkEl = this._codeArea.querySelector("a") as HTMLAnchorElement;
linkEl.textContent = code.replace(/-/g, '-');
if (this.label == "") {
linkEl.textContent = code.replace(/-/g, '-');
}
linkEl.href = this._codeLink;
}
private _codeLink: string;
@ -345,6 +358,9 @@ export class DOMInvite implements Invite {
this.profile = invite.profile;
this.remainingUses = invite.remainingUses;
this.usedBy = invite.usedBy;
if (invite.label) {
this.label = invite.label;
}
}
asElement = (): HTMLDivElement => { return this._container; }
@ -443,6 +459,7 @@ function parseInvite(invite: { [f: string]: string | number | string[][] | boole
let parsed: Invite = {};
parsed.code = invite["code"] as string;
parsed.email = invite["email"] as string || "";
parsed.label = invite["label"] as string || "";
let time = "";
const fields = ["days", "hours", "minutes"];
for (let i = 0; i < fields.length; i++) {
@ -468,6 +485,7 @@ export class createInvite {
private _infUsesWarning = document.getElementById('create-inf-uses-warning') as HTMLParagraphElement;
private _createButton = document.getElementById("create-submit") as HTMLSpanElement;
private _profile = document.getElementById("create-profile") as HTMLSelectElement;
private _label = document.getElementById("create-label") as HTMLInputElement;
private _days = document.getElementById("create-days") as HTMLSelectElement;
private _hours = document.getElementById("create-hours") as HTMLSelectElement;
@ -492,6 +510,9 @@ export class createInvite {
}
}
get label(): string { return this._label.value; }
set label(label: string) { this._label.value = label; }
get sendToEnabled(): boolean {
return this._sendToEnabled.checked;
}
@ -599,7 +620,8 @@ export class createInvite {
"no-limit": this.infiniteUses,
"remaining-uses": this.uses,
"email": this.sendToEnabled ? this.sendTo : "",
"profile": this.profile
"profile": this.profile,
"label": this.label
};
_post("/invites", send, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
@ -623,6 +645,7 @@ export class createInvite {
this._createButton.onclick = this.create;
this.sendTo = "";
this.uses = 1;
this.label = "";
this._days.onchange = this._checkDurationValidity;
this._hours.onchange = this._checkDurationValidity;

View File

@ -86,6 +86,7 @@ interface Invite {
notifyExpiry?: boolean;
notifyCreation?: boolean;
profile?: string;
label?: string;
}
interface inviteList {