diff --git a/Changelog.md b/Changelog.md index 9d012ecf..e8e4dc3c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ ### Added - Added an inline DNS TXT record guide and domain verification controls to App Configuration. +- Added direct URL access to the General, Domain Verification, and Issuer Configuration tabs. ### Changed diff --git a/src/App.vue b/src/App.vue index 68d065d1..c6dec817 100644 --- a/src/App.vue +++ b/src/App.vue @@ -454,7 +454,6 @@ color: #1a1a2e !important; font-size: 0.65rem; font-weight: 700; letter-spacing: 0.03em; - text-transform: uppercase; border-radius: 14px; } @@ -586,7 +585,7 @@ color: #1a1a2e !important;
- DEV + Development
diff --git a/src/store/mainStore.js b/src/store/mainStore.js index b357fcda..1796c987 100644 --- a/src/store/mainStore.js +++ b/src/store/mainStore.js @@ -728,7 +728,7 @@ const mainStore = { resolve(json) } }).catch((e) => { - reject(new Error(`while updating an app ${e}`)) + reject(new Error(`${e}`)) }) }) }, @@ -936,7 +936,7 @@ const mainStore = { resolve(json) } }).catch((e) => { - reject(new Error(`while updating an app ${e}`)) + reject(new Error(`${e}`)) }) }) }, @@ -963,7 +963,7 @@ const mainStore = { } }) .catch(e => { - reject(new Error(`while updating an app ${e}`)); + reject(new Error(`${e}`)); }); }); }, diff --git a/src/views/ServiceConfig.vue b/src/views/ServiceConfig.vue index 65da896b..dde85101 100644 --- a/src/views/ServiceConfig.vue +++ b/src/views/ServiceConfig.vue @@ -112,7 +112,7 @@ {{ displayDomainVerified ? '✓ Verified' : 'Unverified' }} -

Confirm ownership of the domain used by this application.

+

Verify domain ownership to unlock Production access.

Switching environments can affect credentials, integrations, and available services.

+

Your domain must be verified before moving to Production.

+

The environment change will be applied when you save.

@@ -354,7 +356,6 @@ .domain-summary { width: 100%; } .domain-summary strong { font-size: 13px; } .card-footer-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 22px; padding-top: 18px; border-top: 1px solid #e8edf3; } -.domain-footer-actions { margin-top: 16px; padding-top: 0; border-top: 0; } .verification-badge, .inline-verified, .key-type { display: inline-flex; align-items: center; border-radius: 14px; font-size: 11px; font-weight: 700; } .verification-badge { padding: 5px 10px; } .verified, .inline-verified { background: #eaf8f0; color: #218459; } @@ -366,6 +367,7 @@ .environment-toggle button:disabled { cursor: default; opacity: 1; } .environment-help { margin: 14px 0 0; color: #7b8798; font-size: 11px; } .pending-message { margin: 12px 0 0; color: #218459; font-size: 12px; } +.production-requirement { margin: 10px 0 0; padding: 9px 10px; border-radius: 6px; background: #fff8e8; color: #8a611d; font-size: 11px; line-height: 1.45; } .identity-fields { display: grid; gap: 22px; margin-top: 24px; } .key-type { margin-top: 7px; padding: 4px 8px; background: #f0f4ff; color: #315fba; } .dns-record { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding: 14px; border: 1px solid #dfe6ef; border-radius: 7px; background: #f8fafc; } @@ -483,6 +485,13 @@ export default { .map(value => normalizeCorsOrigin(value)) .filter(Boolean) .filter((origin, index, all) => all.indexOf(origin) === index); + this.activeTab = this.isValidTab(this.$route.query.tab) ? this.$route.query.tab : 'general'; + }, + watch: { + '$route.query.tab'(tab) { + if (this.isEditing || this.isEditingDomain) return; + this.activeTab = this.isValidTab(tab) ? tab : 'general'; + }, }, methods: { ...mapActions('mainStore', [ @@ -496,9 +505,21 @@ export default { return serviceId ? this.getAppsWithSSIServices.find(item => item.appId === serviceId) : null; }, async selectTab(tab) { + if (!this.isValidTab(tab)) return; this.activeTab = tab; + if (this.$route.query.tab !== tab) { + await this.$router.replace({ + query: { + ...this.$route.query, + tab, + }, + }); + } if (tab === 'issuer' && this.isEditing && this.editingSection === 'issuer') await this.prepareIdentityEditor(); }, + isValidTab(tab) { + return this.tabs.some(item => item.value === tab); + }, async prepareIdentityEditor() { await this.ensureWidgetConfigsLoaded(); if (!this.associatedSSIServiceDIDs.length) await this.fetchDIDs();