diff --git a/panel/lab/components/login/login-code/index.php b/panel/lab/components/login/login-code/index.php
new file mode 100644
index 0000000000..939f9c01da
--- /dev/null
+++ b/panel/lab/components/login/login-code/index.php
@@ -0,0 +1,5 @@
+ 'k-login-code'
+];
diff --git a/panel/lab/components/login/login-code/index.vue b/panel/lab/components/login/login-code/index.vue
new file mode 100644
index 0000000000..a9581334a8
--- /dev/null
+++ b/panel/lab/components/login/login-code/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/panel/lab/components/login/login/index.php b/panel/lab/components/login/login/index.php
new file mode 100644
index 0000000000..681fdf8c82
--- /dev/null
+++ b/panel/lab/components/login/login/index.php
@@ -0,0 +1,5 @@
+ 'k-login'
+];
diff --git a/panel/lab/components/login/login/index.vue b/panel/lab/components/login/login/index.vue
new file mode 100644
index 0000000000..7b201b4df2
--- /dev/null
+++ b/panel/lab/components/login/login/index.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/panel/src/components/Forms/Login.vue b/panel/src/components/Forms/Login.vue
index 27b2535048..7539690151 100644
--- a/panel/src/components/Forms/Login.vue
+++ b/panel/src/components/Forms/Login.vue
@@ -5,7 +5,7 @@
v-if="canToggle === true"
class="k-login-toggler"
type="button"
- @click="toggleForm"
+ @click="toggle"
>
{{ toggleText }}
@@ -19,14 +19,15 @@
/>
-
-
-
-
+
+
@@ -48,12 +48,18 @@ export const props = {
/**
* List of available login method names
*/
- methods: Array,
+ methods: {
+ type: Array,
+ default: () => []
+ },
/**
* Values to prefill the inputs
- * @value { email: String, password: String }
+ * @value { email: String, password: String, remember: Boolean }
*/
- value: Object
+ value: {
+ type: Object,
+ default: () => ({})
+ }
}
};
@@ -62,22 +68,36 @@ export default {
emits: ["error"],
data() {
return {
- currentForm: null,
+ mode: null,
isLoading: false,
user: {
- email: this.value.email ?? "",
- password: this.value.password ?? "",
- remember: false
+ email: "",
+ password: "",
+ remember: false,
+ ...this.value
}
};
},
computed: {
+ alternateMode() {
+ if (this.form === "email-password") {
+ return "email";
+ }
+
+ return "email-password";
+ },
canToggle() {
+ if (this.codeMode === null) {
+ return false;
+ }
+
+ if (this.methods.includes("password") === false) {
+ return false;
+ }
+
return (
- this.codeMode !== null &&
- this.methods.includes("password") === true &&
- (this.methods.includes("password-reset") === true ||
- this.methods.includes("code") === true)
+ this.methods.includes("password-reset") === true ||
+ this.methods.includes("code") === true
);
},
codeMode() {
@@ -90,7 +110,7 @@ export default {
return null;
},
fields() {
- let fields = {
+ const fields = {
email: {
autofocus: true,
label: this.$t("email"),
@@ -114,8 +134,8 @@ export default {
return fields;
},
form() {
- if (this.currentForm) {
- return this.currentForm;
+ if (this.mode) {
+ return this.mode;
}
if (this.methods[0] === "password") {
@@ -127,28 +147,30 @@ export default {
isResetForm() {
return this.codeMode === "password-reset" && this.form === "email";
},
+ submitText() {
+ const suffix = this.isLoading ? " …" : "";
+
+ if (this.isResetForm) {
+ return this.$t("login.reset") + suffix;
+ }
+
+ return this.$t("login") + suffix;
+ },
toggleText() {
return this.$t(
- "login.toggleText." + this.codeMode + "." + this.formOpposite(this.form)
+ "login.toggleText." + this.codeMode + "." + this.alternateMode
);
}
},
methods: {
- formOpposite(input) {
- if (input === "email-password") {
- return "email";
- } else {
- return "email-password";
- }
- },
async login() {
this.$emit("error", null);
this.isLoading = true;
// clear field data that is not needed for login
- let user = Object.assign({}, this.user);
+ const user = { ...this.user };
- if (this.currentForm === "email") {
+ if (this.mode === "email") {
user.password = null;
}
@@ -173,10 +195,35 @@ export default {
this.isLoading = false;
}
},
- toggleForm() {
- this.currentForm = this.formOpposite(this.form);
+ toggle() {
+ this.mode = this.alternateMode;
this.$refs.fieldset.focus("email");
}
}
};
+
+
diff --git a/panel/src/components/Forms/LoginCode.vue b/panel/src/components/Forms/LoginCode.vue
index 642dcf9b2d..bd9addd7d3 100644
--- a/panel/src/components/Forms/LoginCode.vue
+++ b/panel/src/components/Forms/LoginCode.vue
@@ -1,6 +1,6 @@
@@ -49,12 +48,18 @@ export const props = {
/**
* List of available login method names
*/
- methods: Array,
+ methods: {
+ type: Array,
+ default: () => []
+ },
/**
* Pending login data (user email, challenge type)
* @value { email: String, challenge: String }
*/
- pending: Object,
+ pending: {
+ type: Object,
+ default: () => ({ challenge: "email" })
+ },
/**
* Code value to prefill the input
*/
@@ -68,27 +73,29 @@ export default {
data() {
return {
code: this.value ?? "",
- isLoadingBack: false,
- isLoadingLogin: false
+ isLoading: false
};
},
computed: {
mode() {
- if (this.methods.includes("password-reset") === true) {
- return "password-reset";
+ return this.methods.includes("password-reset")
+ ? "password-reset"
+ : "login";
+ },
+ submitText() {
+ const suffix = this.isLoading ? " …" : "";
+
+ if (this.mode === "password-reset") {
+ return this.$t("login.reset") + suffix;
}
- return "login";
+ return this.$t("login") + suffix;
}
},
methods: {
- async back() {
- this.isLoadingBack = true;
- this.$go("/logout");
- },
async login() {
this.$emit("error", null);
- this.isLoadingLogin = true;
+ this.isLoading = true;
try {
await this.$api.auth.verifyCode(this.code);
@@ -106,7 +113,7 @@ export default {
} catch (error) {
this.$emit("error", error);
} finally {
- this.isLoadingLogin = false;
+ this.isLoading = false;
}
}
}
diff --git a/panel/src/components/Views/Login/LoginView.vue b/panel/src/components/Views/Login/LoginView.vue
index 4552b4d817..4118caa96b 100644
--- a/panel/src/components/Views/Login/LoginView.vue
+++ b/panel/src/components/Views/Login/LoginView.vue
@@ -1,7 +1,9 @@
-
+
-
+
{{ $t("login") }}
@@ -16,7 +18,12 @@
v-bind="{ methods, pending, value: value.code }"
@error="onError"
/>
-
+
@@ -24,14 +31,14 @@