feat: add option for users to select their preferred way of formatting date times
parent
83898d616f
commit
4bd630933e
36
auth/hook.go
36
auth/hook.go
|
@ -157,16 +157,17 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
|||
|
||||
// create user with the provided credentials
|
||||
d := &users.User{
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
DateTimeFormat: a.Settings.Defaults.DateTimeFormat,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
}
|
||||
u = a.GetUser(d)
|
||||
|
||||
|
@ -218,13 +219,14 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
|
|||
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
|
||||
}
|
||||
user := users.User{
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
DateTimeFormat: a.Fields.GetString("user.dateTimeFormat", d.DateTimeFormat),
|
||||
Sorting: files.Sorting{
|
||||
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
|
||||
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
|
||||
|
|
|
@ -166,6 +166,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
|||
fmt.Fprintln(w, "\nDefaults:")
|
||||
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||
fmt.Fprintf(w, "\tDateTimeFormat:\t%s\n", set.Defaults.DateTimeFormat)
|
||||
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
|
||||
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
|
||||
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
||||
|
|
|
@ -323,9 +323,10 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
|||
CreateUserDir: false,
|
||||
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
|
||||
Defaults: settings.UserDefaults{
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
DateTimeFormat: "MM/DD/YYYY h:mm A",
|
||||
SingleClick: false,
|
||||
Perm: users.Permissions{
|
||||
Admin: false,
|
||||
Execute: true,
|
||||
|
|
|
@ -27,10 +27,10 @@ var usersCmd = &cobra.Command{
|
|||
|
||||
func printUsers(usrs []*users.User) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock\tDateTimeFormat")
|
||||
|
||||
for _, u := range usrs {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%s\t\n",
|
||||
u.ID,
|
||||
u.Username,
|
||||
u.Scope,
|
||||
|
@ -46,6 +46,7 @@ func printUsers(usrs []*users.User) {
|
|||
u.Perm.Share,
|
||||
u.Perm.Download,
|
||||
u.LockPassword,
|
||||
u.DateTimeFormat,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -75,6 +76,7 @@ func addUserFlags(flags *pflag.FlagSet) {
|
|||
flags.StringSlice("commands", nil, "a list of the commands a user can execute")
|
||||
flags.String("scope", ".", "scope for users")
|
||||
flags.String("locale", "en", "locale for users")
|
||||
flags.String("dateTimeFormat", "MM/DD/YYYY h:mm A", "date time format for users")
|
||||
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
||||
flags.Bool("singleClick", false, "use single clicks only")
|
||||
}
|
||||
|
|
|
@ -41,17 +41,19 @@ options you want to change.`,
|
|||
checkErr(err)
|
||||
|
||||
defaults := settings.UserDefaults{
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
DateTimeFormat: user.DateTimeFormat,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
}
|
||||
getUserDefaults(flags, &defaults, false)
|
||||
user.Scope = defaults.Scope
|
||||
user.Locale = defaults.Locale
|
||||
user.DateTimeFormat = defaults.DateTimeFormat
|
||||
user.ViewMode = defaults.ViewMode
|
||||
user.SingleClick = defaults.SingleClick
|
||||
user.Perm = defaults.Perm
|
||||
|
|
|
@ -110,7 +110,8 @@ const humanSize = () => {
|
|||
|
||||
const humanTime = () => {
|
||||
if (!props.readOnly && authStore.user?.dateFormat) {
|
||||
return dayjs(props.modified).format("L LT");
|
||||
const format = authStore.user?.dateTimeFormat || "L LT";
|
||||
return dayjs(props.modified).format(format);
|
||||
}
|
||||
return dayjs(props.modified).fromNow();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<select
|
||||
name="selectDateTimeFormat"
|
||||
v-on:change="change"
|
||||
:value="dateTimeFormat"
|
||||
>
|
||||
<option
|
||||
v-for="(dateTimeFormat, value) in dateTimeFormats"
|
||||
:key="value"
|
||||
:value="value"
|
||||
>
|
||||
{{ dateTimeFormat }}
|
||||
</option>
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { markRaw } from "vue";
|
||||
|
||||
export default {
|
||||
name: "dateTimeFormats",
|
||||
props: ["dateTimeFormat"],
|
||||
data() {
|
||||
let dataObj = {};
|
||||
const dateTimeFormats = {
|
||||
"MM/DD/YYYY h:mm A": "02/21/2023 3:59 PM",
|
||||
"YYYY/MM/DD HH:mm": "2023/02/21 15:59",
|
||||
"DD/MM/YYYY HH:mm": "21/02/2023 15:59",
|
||||
};
|
||||
|
||||
// Vue3 reactivity breaks with this configuration
|
||||
// so we need to use markRaw as a workaround
|
||||
// https://github.com/vuejs/core/issues/3024
|
||||
Object.defineProperty(dataObj, "dateTimeFormats", {
|
||||
value: markRaw(dateTimeFormats),
|
||||
configurable: false,
|
||||
writable: false,
|
||||
});
|
||||
|
||||
return dataObj;
|
||||
},
|
||||
methods: {
|
||||
change(event) {
|
||||
this.$emit("update:dateTimeFormat", event.target.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -191,6 +191,7 @@
|
|||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "Language",
|
||||
"dateTimeFormat": "Date and time format",
|
||||
"lockPassword": "Prevent the user from changing the password",
|
||||
"newPassword": "Your new password",
|
||||
"newPasswordConfirm": "Confirm your new password",
|
||||
|
|
|
@ -13,6 +13,7 @@ interface ISettings {
|
|||
interface SettingsDefaults {
|
||||
scope: string;
|
||||
locale: string;
|
||||
dateTimeFormat: string;
|
||||
viewMode: ViewModeType;
|
||||
singleClick: boolean;
|
||||
sorting: Sorting;
|
||||
|
|
|
@ -4,6 +4,7 @@ interface IUser {
|
|||
password: string;
|
||||
scope: string;
|
||||
locale: string;
|
||||
dateTimeFormat: string;
|
||||
perm: Permissions;
|
||||
commands: string[];
|
||||
rules: IRule[];
|
||||
|
@ -23,6 +24,7 @@ interface IUserForm {
|
|||
password?: string;
|
||||
scope?: string;
|
||||
locale?: string;
|
||||
dateTimeFormat?: string;
|
||||
perm?: Permissions;
|
||||
commands?: string[];
|
||||
rules?: IRule[];
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
class="input input--block"
|
||||
v-model:locale="locale"
|
||||
></languages>
|
||||
<h3>{{ t("settings.dateTimeFormat") }}</h3>
|
||||
<date-time-format
|
||||
class="input input--block"
|
||||
v-model:dateTimeFormat="dateTimeFormatValue"
|
||||
></date-time-format>
|
||||
</div>
|
||||
|
||||
<div class="card-action">
|
||||
|
@ -82,6 +87,7 @@ import { useAuthStore } from "@/stores/auth";
|
|||
import { useLayoutStore } from "@/stores/layout";
|
||||
import { users as api } from "@/api";
|
||||
import Languages from "@/components/settings/Languages.vue";
|
||||
import DateTimeFormat from "@/components/settings/DateTimeFormats.vue";
|
||||
import { computed, inject, onMounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
|
@ -97,6 +103,7 @@ const passwordConf = ref<string>("");
|
|||
const hideDotfiles = ref<boolean>(false);
|
||||
const singleClick = ref<boolean>(false);
|
||||
const dateFormat = ref<boolean>(false);
|
||||
const dateTimeFormatValue = ref<string>("");
|
||||
const locale = ref<string>("");
|
||||
|
||||
const passwordClass = computed(() => {
|
||||
|
@ -117,6 +124,7 @@ onMounted(() => {
|
|||
layoutStore.loading = true;
|
||||
if (authStore.user === null) return false;
|
||||
locale.value = authStore.user.locale;
|
||||
dateTimeFormatValue.value = authStore.user.dateTimeFormat;
|
||||
hideDotfiles.value = authStore.user.hideDotfiles;
|
||||
singleClick.value = authStore.user.singleClick;
|
||||
dateFormat.value = authStore.user.dateFormat;
|
||||
|
@ -160,6 +168,7 @@ const updateSettings = async (event: Event) => {
|
|||
...authStore.user,
|
||||
id: authStore.user.id,
|
||||
locale: locale.value,
|
||||
dateTimeFormat: dateTimeFormatValue.value,
|
||||
hideDotfiles: hideDotfiles.value,
|
||||
singleClick: singleClick.value,
|
||||
dateFormat: dateFormat.value,
|
||||
|
@ -170,6 +179,7 @@ const updateSettings = async (event: Event) => {
|
|||
"hideDotfiles",
|
||||
"singleClick",
|
||||
"dateFormat",
|
||||
"dateTimeFormat",
|
||||
]);
|
||||
authStore.updateUser(data);
|
||||
$showSuccess(t("settings.settingsUpdated"));
|
||||
|
|
38
http/auth.go
38
http/auth.go
|
@ -21,15 +21,16 @@ const (
|
|||
)
|
||||
|
||||
type userInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
DateTimeFormat string `json:"dateTimeFormat"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
}
|
||||
|
||||
type authToken struct {
|
||||
|
@ -186,15 +187,16 @@ func renewHandler(tokenExpireTime time.Duration) handleFunc {
|
|||
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) {
|
||||
claims := &authToken{
|
||||
User: userInfo{
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
DateTimeFormat: user.DateTimeFormat,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
},
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
|
|
|
@ -8,21 +8,23 @@ import (
|
|||
// UserDefaults is a type that holds the default values
|
||||
// for some fields on User.
|
||||
type UserDefaults struct {
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
DateTimeFormat string `json:"dateTimeFormat"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
}
|
||||
|
||||
// Apply applies the default options to a user.
|
||||
func (d *UserDefaults) Apply(u *users.User) {
|
||||
u.Scope = d.Scope
|
||||
u.Locale = d.Locale
|
||||
u.DateTimeFormat = d.DateTimeFormat
|
||||
u.ViewMode = d.ViewMode
|
||||
u.SingleClick = d.SingleClick
|
||||
u.Perm = d.Perm
|
||||
|
|
|
@ -21,21 +21,22 @@ const (
|
|||
|
||||
// User describes a user.
|
||||
type User struct {
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
DateTimeFormat string `json:"dateTimeFormat"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
}
|
||||
|
||||
// GetRules implements rules.Provider.
|
||||
|
|
Loading…
Reference in New Issue