From a4f31697f49dac8fe5e4bcda9979680541b0c571 Mon Sep 17 00:00:00 2001
From: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Date: Wed, 12 Jan 2022 23:11:24 +0800
Subject: [PATCH] Enable context menu for read-only fields & adds copy/paste
options (#10992)
* allow viewing of raw value for read only fields
* add copy value to form-field-menu
* change raw value dialog title when disabled
* fix notify typing
* add paste option & notification for copy/paste
---
app/src/components/v-form/form-field-menu.vue | 41 ++++++++-----
app/src/components/v-form/form-field.vue | 59 ++++++++++++++++---
app/src/lang/translations/en-US.yaml | 13 +++-
app/src/utils/notify.ts | 4 +-
4 files changed, 91 insertions(+), 26 deletions(-)
diff --git a/app/src/components/v-form/form-field-menu.vue b/app/src/components/v-form/form-field-menu.vue
index 52bde20ecd..6d3944ebc8 100644
--- a/app/src/components/v-form/form-field-menu.vue
+++ b/app/src/components/v-form/form-field-menu.vue
@@ -1,16 +1,20 @@
-
-
- {{ t('clear_value') }}
+
+
+ {{ restricted ? t('view_raw_value') : t('edit_raw_value') }}
+
+
+ {{ t('copy_raw_value') }}
+
+
+
+ {{ t('paste_raw_value') }}
+
+
{{ t('reset_to_default') }}
{{ t('undo_changes') }}
-
-
- {{ t('raw_value') }}
+
+
+ {{ t('clear_value') }}
@@ -57,8 +66,12 @@ export default defineComponent({
type: [String, Number, Object, Array, Boolean],
default: null,
},
+ restricted: {
+ type: Boolean,
+ default: false,
+ },
},
- emits: ['update:modelValue', 'unset', 'edit-raw'],
+ emits: ['update:modelValue', 'unset', 'edit-raw', 'copy-raw', 'paste-raw'],
setup(props) {
const { t } = useI18n();
diff --git a/app/src/components/v-form/form-field.vue b/app/src/components/v-form/form-field.vue
index 16632aff4d..56382ec959 100644
--- a/app/src/components/v-form/form-field.vue
+++ b/app/src/components/v-form/form-field.vue
@@ -1,12 +1,11 @@
-
+
@@ -42,9 +44,9 @@
- {{ t('edit_raw_value') }}
+ {{ isDisabled ? t('view_raw_value') : t('edit_raw_value') }}
-
+
{{ t('done') }}
@@ -68,6 +70,7 @@ import FormFieldLabel from './form-field-label.vue';
import FormFieldMenu from './form-field-menu.vue';
import FormFieldInterface from './form-field-interface.vue';
import { getJSType } from '@/utils/get-js-type';
+import { notify } from '@/utils/notify';
import { isEqual } from 'lodash';
export default defineComponent({
@@ -146,7 +149,7 @@ export default defineComponent({
return props.modelValue !== undefined && isEqual(props.modelValue, props.initialValue) === false;
});
- const { showRaw, rawValue } = useRaw();
+ const { showRaw, rawValue, copyRaw, pasteRaw } = useRaw();
const validationMessage = computed(() => {
if (!props.validationError) return null;
@@ -158,7 +161,18 @@ export default defineComponent({
}
});
- return { t, isDisabled, internalValue, emitValue, showRaw, rawValue, validationMessage, isEdited };
+ return {
+ t,
+ isDisabled,
+ internalValue,
+ emitValue,
+ showRaw,
+ rawValue,
+ copyRaw,
+ pasteRaw,
+ validationMessage,
+ isEdited,
+ };
function emitValue(value: any) {
if (
@@ -212,7 +226,38 @@ export default defineComponent({
},
});
- return { showRaw, rawValue };
+ async function copyRaw() {
+ try {
+ await navigator?.clipboard?.writeText(rawValue.value);
+ notify({
+ type: 'success',
+ title: t('copy_raw_value_success'),
+ });
+ } catch (err: any) {
+ notify({
+ type: 'error',
+ title: t('copy_raw_value_fail'),
+ });
+ }
+ }
+
+ async function pasteRaw() {
+ try {
+ const pasteValue = await navigator?.clipboard?.readText();
+ rawValue.value = pasteValue;
+ notify({
+ type: 'success',
+ title: t('paste_raw_value_success'),
+ });
+ } catch (err: any) {
+ notify({
+ type: 'error',
+ title: t('paste_raw_value_fail'),
+ });
+ }
+ }
+
+ return { showRaw, rawValue, copyRaw, pasteRaw };
}
},
});
diff --git a/app/src/lang/translations/en-US.yaml b/app/src/lang/translations/en-US.yaml
index 34151a94af..fc3830d5ca 100644
--- a/app/src/lang/translations/en-US.yaml
+++ b/app/src/lang/translations/en-US.yaml
@@ -289,12 +289,19 @@ foreign_key: Foreign Key
finish_setup: Finish Setup
dismiss: Dismiss
raw_value: Raw value
+copy_raw_value: Copy Raw Value
+copy_raw_value_success: Copied
+copy_raw_value_fail: Copy Failed
+paste_raw_value: Paste Raw Value
+paste_raw_value_success: Pasted
+paste_raw_value_fail: Paste Failed
+view_raw_value: View Raw Value
edit_raw_value: Edit Raw Value
enter_raw_value: Enter raw value...
-clear_value: Clear value
+clear_value: Clear Value
clear_changes: Clear Changes
-reset_to_default: Reset to default
-undo_changes: Undo changes
+reset_to_default: Reset to Default
+undo_changes: Undo Changes
notifications: Notifications
show_all_activity: Show All Activity
page_not_found: Page Not Found
diff --git a/app/src/utils/notify.ts b/app/src/utils/notify.ts
index 0bb961fe91..5b58aa0b10 100644
--- a/app/src/utils/notify.ts
+++ b/app/src/utils/notify.ts
@@ -1,9 +1,9 @@
import { useNotificationsStore } from '@/stores/';
-import { NotificationRaw } from '@/types';
+import { SnackbarRaw } from '@/types';
let store: any;
-export function notify(notification: NotificationRaw): void {
+export function notify(notification: SnackbarRaw): void {
if (!store) store = useNotificationsStore();
store.add(notification);
}