mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-03 12:37:56 +00:00
feat: Revamp access token section in profile settings (#9328)
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex flex-row justify-between gap-4">
|
||||||
|
<woot-input
|
||||||
|
name="access_token"
|
||||||
|
class="flex-1 focus:[&>input]:!border-slate-200 focus:[&>input]:dark:!border-slate-600 [&>input]:cursor-not-allowed"
|
||||||
|
:styles="{
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '6px 12px',
|
||||||
|
fontSize: '14px',
|
||||||
|
marginBottom: '2px',
|
||||||
|
}"
|
||||||
|
type="password"
|
||||||
|
:value="value"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
|
<form-button
|
||||||
|
type="submit"
|
||||||
|
size="large"
|
||||||
|
icon="text-copy"
|
||||||
|
variant="outline"
|
||||||
|
color-scheme="secondary"
|
||||||
|
@click="onClick"
|
||||||
|
>
|
||||||
|
{{ $t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.COPY') }}
|
||||||
|
</form-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import FormButton from 'v3/components/Form/Button.vue';
|
||||||
|
const props = defineProps({
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['on-copy']);
|
||||||
|
const onClick = () => {
|
||||||
|
emit('on-copy', props.value);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
/>
|
/>
|
||||||
</form-section>
|
</form-section>
|
||||||
<form-section
|
<form-section
|
||||||
:header="$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.TITLE')"
|
:title="$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.TITLE')"
|
||||||
:description="$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.NOTE')"
|
:description="$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.NOTE')"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -58,23 +58,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</form-section>
|
</form-section>
|
||||||
<form-section
|
<form-section
|
||||||
:header="$t('PROFILE_SETTINGS.FORM.PASSWORD_SECTION.TITLE')"
|
:title="$t('PROFILE_SETTINGS.FORM.PASSWORD_SECTION.TITLE')"
|
||||||
>
|
>
|
||||||
<change-password v-if="!globalConfig.disableUserProfileUpdate" />
|
<change-password v-if="!globalConfig.disableUserProfileUpdate" />
|
||||||
</form-section>
|
</form-section>
|
||||||
<form-section
|
<form-section
|
||||||
:header="
|
:title="$t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.TITLE')"
|
||||||
$t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.TITLE')
|
|
||||||
"
|
|
||||||
:description="
|
:description="
|
||||||
$t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.NOTE')
|
$t('PROFILE_SETTINGS.FORM.AUDIO_NOTIFICATIONS_SECTION.NOTE')
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<audio-notifications />
|
<audio-notifications />
|
||||||
</form-section>
|
</form-section>
|
||||||
<form-section :header="$t('PROFILE_SETTINGS.FORM.NOTIFICATIONS.TITLE')">
|
<form-section :title="$t('PROFILE_SETTINGS.FORM.NOTIFICATIONS.TITLE')">
|
||||||
<notification-preferences />
|
<notification-preferences />
|
||||||
</form-section>
|
</form-section>
|
||||||
|
<form-section
|
||||||
|
:title="$t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.TITLE')"
|
||||||
|
:description="
|
||||||
|
useInstallationName(
|
||||||
|
$t('PROFILE_SETTINGS.FORM.ACCESS_TOKEN.NOTE'),
|
||||||
|
globalConfig.installationName
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<access-token
|
||||||
|
:value="currentUser.access_token"
|
||||||
|
@on-copy="onCopyToken"
|
||||||
|
/>
|
||||||
|
</form-section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,6 +99,7 @@ import uiSettingsMixin, {
|
|||||||
import alertMixin from 'shared/mixins/alertMixin';
|
import alertMixin from 'shared/mixins/alertMixin';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { clearCookiesOnLogout } from 'dashboard/store/utils/api.js';
|
import { clearCookiesOnLogout } from 'dashboard/store/utils/api.js';
|
||||||
|
import { copyTextToClipboard } from 'shared/helpers/clipboard';
|
||||||
|
|
||||||
import UserProfilePicture from './UserProfilePicture.vue';
|
import UserProfilePicture from './UserProfilePicture.vue';
|
||||||
import UserBasicDetails from './UserBasicDetails.vue';
|
import UserBasicDetails from './UserBasicDetails.vue';
|
||||||
@@ -96,6 +109,7 @@ import ChangePassword from './ChangePassword.vue';
|
|||||||
import NotificationPreferences from './NotificationPreferences.vue';
|
import NotificationPreferences from './NotificationPreferences.vue';
|
||||||
import AudioNotifications from './AudioNotifications.vue';
|
import AudioNotifications from './AudioNotifications.vue';
|
||||||
import FormSection from 'dashboard/components/FormSection.vue';
|
import FormSection from 'dashboard/components/FormSection.vue';
|
||||||
|
import AccessToken from './AccessToken.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -107,6 +121,7 @@ export default {
|
|||||||
ChangePassword,
|
ChangePassword,
|
||||||
NotificationPreferences,
|
NotificationPreferences,
|
||||||
AudioNotifications,
|
AudioNotifications,
|
||||||
|
AccessToken,
|
||||||
},
|
},
|
||||||
mixins: [alertMixin, globalConfigMixin, uiSettingsMixin],
|
mixins: [alertMixin, globalConfigMixin, uiSettingsMixin],
|
||||||
data() {
|
data() {
|
||||||
@@ -240,6 +255,10 @@ export default {
|
|||||||
this.$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.UPDATE_SUCCESS')
|
this.$t('PROFILE_SETTINGS.FORM.SEND_MESSAGE.UPDATE_SUCCESS')
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
async onCopyToken(value) {
|
||||||
|
await copyTextToClipboard(value);
|
||||||
|
this.showAlert(this.$t('COMPONENTS.CODE.COPY_SUCCESSFUL'));
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -274,5 +274,6 @@
|
|||||||
"chevron-left-single-outline": "m15 18-6-6 6-6",
|
"chevron-left-single-outline": "m15 18-6-6 6-6",
|
||||||
"chevrons-right-outline": ["m6 17 5-5-5-5", "m13 17 5-5-5-5"],
|
"chevrons-right-outline": ["m6 17 5-5-5-5", "m13 17 5-5-5-5"],
|
||||||
"chevron-right-single-outline": "m9 18 6-6-6-6",
|
"chevron-right-single-outline": "m9 18 6-6-6-6",
|
||||||
"avatar-upload-outline": "M19.754 11a.75.75 0 0 1 .743.648l.007.102v7a3.25 3.25 0 0 1-3.065 3.246l-.185.005h-11a3.25 3.25 0 0 1-3.244-3.066l-.006-.184V11.75a.75.75 0 0 1 1.494-.102l.006.102v7a1.75 1.75 0 0 0 1.607 1.745l.143.006h11A1.75 1.75 0 0 0 19 18.894l.005-.143V11.75a.75.75 0 0 1 .75-.75ZM6.22 7.216l4.996-4.996a.75.75 0 0 1 .976-.073l.084.072l5.005 4.997a.75.75 0 0 1-.976 1.134l-.084-.073l-3.723-3.716l.001 11.694a.75.75 0 0 1-.648.743l-.102.007a.75.75 0 0 1-.743-.648L11 16.255V4.558L7.28 8.277a.75.75 0 0 1-.976.073l-.084-.073a.75.75 0 0 1-.073-.977l.073-.084l4.996-4.996L6.22 7.216Z"
|
"avatar-upload-outline": "M19.754 11a.75.75 0 0 1 .743.648l.007.102v7a3.25 3.25 0 0 1-3.065 3.246l-.185.005h-11a3.25 3.25 0 0 1-3.244-3.066l-.006-.184V11.75a.75.75 0 0 1 1.494-.102l.006.102v7a1.75 1.75 0 0 0 1.607 1.745l.143.006h11A1.75 1.75 0 0 0 19 18.894l.005-.143V11.75a.75.75 0 0 1 .75-.75ZM6.22 7.216l4.996-4.996a.75.75 0 0 1 .976-.073l.084.072l5.005 4.997a.75.75 0 0 1-.976 1.134l-.084-.073l-3.723-3.716l.001 11.694a.75.75 0 0 1-.648.743l-.102.007a.75.75 0 0 1-.743-.648L11 16.255V4.558L7.28 8.277a.75.75 0 0 1-.976.073l-.084-.073a.75.75 0 0 1-.073-.977l.073-.084l4.996-4.996L6.22 7.216Z",
|
||||||
|
"text-copy-outline": "M5.503 4.627L5.5 6.75v10.504a3.25 3.25 0 0 0 3.25 3.25h8.616a2.25 2.25 0 0 1-2.122 1.5H8.75A4.75 4.75 0 0 1 4 17.254V6.75c0-.98.627-1.815 1.503-2.123M17.75 2A2.25 2.25 0 0 1 20 4.25v13a2.25 2.25 0 0 1-2.25 2.25h-9a2.25 2.25 0 0 1-2.25-2.25v-13A2.25 2.25 0 0 1 8.75 2zm0 1.5h-9a.75.75 0 0 0-.75.75v13c0 .414.336.75.75.75h9a.75.75 0 0 0 .75-.75v-13a.75.75 0 0 0-.75-.75"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
class="inline-flex items-center gap-1 text-sm font-medium reset-base rounded-xl w-fit"
|
class="inline-flex items-center gap-1 text-sm font-medium reset-base rounded-xl w-fit"
|
||||||
:class="buttonClasses"
|
:class="buttonClasses"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
@click="onClick"
|
||||||
>
|
>
|
||||||
<fluent-icon
|
<fluent-icon
|
||||||
v-if="icon && !trailingIcon"
|
v-if="icon && !trailingIcon"
|
||||||
@@ -56,10 +57,10 @@ const props = defineProps({
|
|||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
|
|
||||||
const baseClasses = {
|
const baseClasses = {
|
||||||
outline: 'outline outline-1 -outline-offset-1 focus:ring focus:ring-offset-1',
|
outline: 'outline outline-1 -outline-offset-1',
|
||||||
ghost: 'hover:text-600 active:text-600 focus:ring focus:ring-offset-1',
|
ghost: 'hover:text-600 active:text-600 focus:outline focus:outline-offset-1',
|
||||||
solid:
|
solid:
|
||||||
'hover:bg-700 active:bg-700 focus:ring focus:ring-offset-1 focus:ring-2',
|
'hover:bg-700 active:bg-700 focus:outline focus:outline-offset-1 focus:outline-2',
|
||||||
};
|
};
|
||||||
|
|
||||||
const colorClass = computed(() => {
|
const colorClass = computed(() => {
|
||||||
@@ -69,19 +70,19 @@ const colorClass = computed(() => {
|
|||||||
|
|
||||||
const styleMap = {
|
const styleMap = {
|
||||||
primary: {
|
primary: {
|
||||||
outline: `${baseClasses.outline} outline-primary-400 hover:text-primary-600 active:text-primary-600 focus:ring-primary-400`,
|
outline: `${baseClasses.outline} outline-primary-400 hover:text-primary-600 active:text-primary-600`,
|
||||||
ghost: `${baseClasses.ghost} focus:ring-primary-400`,
|
ghost: `${baseClasses.ghost} focus:outline-primary-400`,
|
||||||
solid: `${baseClasses.solid} bg-primary-600 text-white focus:ring-primary-400`,
|
solid: `${baseClasses.solid} bg-primary-600 text-white focus:outline-primary-400`,
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
outline: `${baseClasses.outline} outline-ash-400 hover:text-ash-600 active:text-ash-600 focus:ring-ash-400`,
|
outline: `${baseClasses.outline} outline-ash-400 hover:text-ash-900 active:text-ash-900 `,
|
||||||
ghost: `${baseClasses.ghost} focus:ring-ash-400`,
|
ghost: `${baseClasses.ghost} focus:outline-ash-400`,
|
||||||
solid: `${baseClasses.solid} bg-ash-100 text-ash-900 focus:ring-ash-400`,
|
solid: `${baseClasses.solid} bg-ash-100 text-ash-900 focus:outline-ash-400`,
|
||||||
},
|
},
|
||||||
danger: {
|
danger: {
|
||||||
outline: `${baseClasses.outline} outline-ruby-400 hover:text-ruby-600 active:text-ruby-600 focus:ring-ruby-400`,
|
outline: `${baseClasses.outline} outline-ruby-400 hover:text-ruby-600 active:text-ruby-600`,
|
||||||
ghost: `${baseClasses.ghost} focus:ring-ruby-400`,
|
ghost: `${baseClasses.ghost} focus:outline-ruby-400`,
|
||||||
solid: `${baseClasses.solid} bg-ruby-600 text-white focus:ring-ruby-400`,
|
solid: `${baseClasses.solid} bg-ruby-600 text-white focus:outline-ruby-400`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,4 +98,13 @@ const sizeClass = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const buttonClasses = computed(() => [colorClass.value, sizeClass.value]);
|
const buttonClasses = computed(() => [colorClass.value, sizeClass.value]);
|
||||||
|
|
||||||
|
const emit = defineEmits(['click']);
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
if (props.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit('click');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user