diff --git a/src/components/settings/Users/AddUser.vue b/src/components/settings/Users/AddUser.vue new file mode 100644 index 000000000..5f38420b8 --- /dev/null +++ b/src/components/settings/Users/AddUser.vue @@ -0,0 +1,94 @@ + + + diff --git a/src/components/settings/Users/EditUser.vue b/src/components/settings/Users/EditUser.vue new file mode 100644 index 000000000..59a8a1747 --- /dev/null +++ b/src/components/settings/Users/EditUser.vue @@ -0,0 +1,205 @@ + + + diff --git a/src/components/settings/Users/Users.vue b/src/components/settings/Users/Users.vue new file mode 100644 index 000000000..e367fd76d --- /dev/null +++ b/src/components/settings/Users/Users.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/src/components/settings/Users/routes.js b/src/components/settings/Users/routes.js new file mode 100644 index 000000000..6d3517455 --- /dev/null +++ b/src/components/settings/Users/routes.js @@ -0,0 +1,29 @@ +import { h } from "vue"; +import { RouterView } from "vue-router"; + +// Needed for settings enter/leave CSS animation +const AnimatedRouterView = () => h("div", [ h(RouterView) ]); +AnimatedRouterView.displayName = "AnimatedRouterView"; + +export default { + path: "users", + component: AnimatedRouterView, + children: [ + { + path: "", + name: "settings.users", + component: () => import("./Users.vue") + }, + { + path: "add", + name: "settings.users.add", + component: () => import("./AddUser.vue") + }, + { + path: "edit/:id", + name: "settings.users.edit", + props: true, + component: () => import("./EditUser.vue") + }, + ] +}; diff --git a/src/icon.js b/src/icon.js index 7bdfe1ca0..b40482783 100644 --- a/src/icon.js +++ b/src/icon.js @@ -50,6 +50,8 @@ import { faInfoCircle, faClone, faCertificate, + faUserSlash, + faUserCheck, } from "@fortawesome/free-solid-svg-icons"; library.add( @@ -97,6 +99,8 @@ library.add( faInfoCircle, faClone, faCertificate, + faUserSlash, + faUserCheck, ); export { FontAwesomeIcon }; diff --git a/src/lang/en.json b/src/lang/en.json index c07e06fab..81fecfae0 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -1051,5 +1051,12 @@ "From":"From", "Can be found on:": "Can be found on: {0}", "The phone number of the recipient in E.164 format.": "The phone number of the recipient in E.164 format.", - "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.":"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies." -} + "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.": "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.", + "Users": "Users", + "Add New User": "Add New User", + "confirmDisableUserMsg": "Are you sure you want to disable this user? The user will not be able to login anymore.", + "Create an admin account": "Create an admin account", + "Identity": "Identity", + "Update Username": "Update Username", + "Permissions": "Permissions" +} \ No newline at end of file diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index d0ed076e1..6dbd88271 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -130,6 +130,13 @@ export default { security: { title: this.$t("Security"), }, + users: { + title: this.$t("Users"), + children: { + add: { title: this.$t("Add") }, + edit: { title: this.$t("Edit") } + }, + }, "api-keys": { title: this.$t("API Keys") }, diff --git a/src/router.js b/src/router.js index bda5078e1..53cf6ac1d 100644 --- a/src/router.js +++ b/src/router.js @@ -27,6 +27,7 @@ import General from "./components/settings/General.vue"; const Notifications = () => import("./components/settings/Notifications.vue"); import ReverseProxy from "./components/settings/ReverseProxy.vue"; import Tags from "./components/settings/Tags.vue"; +import usersSettingsRoutes from "./components/settings/Users/routes.js"; import MonitorHistory from "./components/settings/MonitorHistory.vue"; const Security = () => import("./components/settings/Security.vue"); import Proxies from "./components/settings/Proxies.vue"; @@ -124,6 +125,7 @@ const routes = [ path: "security", component: Security, }, + usersSettingsRoutes, { path: "api-keys", component: APIKeys, diff --git a/src/util-frontend.js b/src/util-frontend.js index d9bf378e5..33fc91a64 100644 --- a/src/util-frontend.js +++ b/src/util-frontend.js @@ -213,3 +213,22 @@ export function getToastErrorTimeout() { return errorTimeout; } + +/** + * Get debounced function + * @returns {Function} debounced function + */ +export function Debounce() { + let timeout = null; + + /** + * exec callback function after delay if no new call to function happens + * @param {Function} callback function to execute after delay + * @param {number} [delay=100] delay before execute the callback if no new call to function happens + * @returns {void} + */ + return function (callback, delay = 100) { + clearTimeout(timeout); + timeout = setTimeout(() => callback(), delay); + }; +}