mirror of
https://github.com/frappe/books.git
synced 2025-02-13 01:18:37 +00:00
incr: add a few more shortcuts
- fix control issue - add a shortcut helper
This commit is contained in:
parent
974c95aafc
commit
765f9f76ce
@ -5,7 +5,6 @@ import { Verb } from 'fyo/telemetry/types';
|
|||||||
import { DEFAULT_USER } from 'fyo/utils/consts';
|
import { DEFAULT_USER } from 'fyo/utils/consts';
|
||||||
import { ConflictError, MandatoryError, NotFoundError } from 'fyo/utils/errors';
|
import { ConflictError, MandatoryError, NotFoundError } from 'fyo/utils/errors';
|
||||||
import Observable from 'fyo/utils/observable';
|
import Observable from 'fyo/utils/observable';
|
||||||
import { Money } from 'pesa';
|
|
||||||
import {
|
import {
|
||||||
DynamicLinkField,
|
DynamicLinkField,
|
||||||
Field,
|
Field,
|
||||||
@ -142,6 +141,10 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.schema.isChild) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.schema.isSubmittable) {
|
if (!this.schema.isSubmittable) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -186,6 +189,14 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.schema.isSingle) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.schema.isChild) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
199
src/components/ShortcutsHelper.vue
Normal file
199
src/components/ShortcutsHelper.vue
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<FormHeader :form-title="t`Shortcuts`" />
|
||||||
|
<hr />
|
||||||
|
<div class="h-96 overflow-y-auto text-gray-900">
|
||||||
|
<template v-for="g in groups" :key="g.label">
|
||||||
|
<div class="p-4 w-full">
|
||||||
|
<!-- Shortcut Group Header -->
|
||||||
|
<div @click="g.collapsed = !g.collapsed" class="cursor-pointer mb-4">
|
||||||
|
<div class="font-semibold">
|
||||||
|
{{ g.label }}
|
||||||
|
</div>
|
||||||
|
<div class="text-base">
|
||||||
|
{{ g.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Shortcuts -->
|
||||||
|
<div v-if="!g.collapsed" class="flex flex-col gap-4">
|
||||||
|
<div
|
||||||
|
v-for="(s, i) in g.shortcuts"
|
||||||
|
:key="g.label + ' ' + i"
|
||||||
|
class="grid gap-4 items-start"
|
||||||
|
style="grid-template-columns: 6rem auto"
|
||||||
|
>
|
||||||
|
<!-- <div class="w-2 text-base">{{ i + 1 }}.</div> -->
|
||||||
|
<div
|
||||||
|
class="
|
||||||
|
text-base
|
||||||
|
font-medium
|
||||||
|
flex-shrink-0 flex
|
||||||
|
items-center
|
||||||
|
gap-1
|
||||||
|
bg-gray-200
|
||||||
|
text-gray-700
|
||||||
|
px-1.5
|
||||||
|
py-0.5
|
||||||
|
rounded
|
||||||
|
"
|
||||||
|
style="width: fit-content"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-for="k in s.shortcut"
|
||||||
|
:key="k"
|
||||||
|
class="tracking-tighter"
|
||||||
|
>{{ k }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="whitespace-normal text-base">{{ s.description }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Shortcut count if collapsed -->
|
||||||
|
<div v-else class="text-base text-gray-600">
|
||||||
|
{{ t`${g.shortcuts.length} shortcuts` }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
</template>
|
||||||
|
<div class="p-4 text-base text-gray-600">
|
||||||
|
{{ t`More shortcuts will be added soon.` }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { t } from 'fyo';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import FormHeader from './FormHeader.vue';
|
||||||
|
|
||||||
|
type Group = {
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
collapsed: boolean;
|
||||||
|
shortcuts: { shortcut: string[]; description: string }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
data() {
|
||||||
|
return { groups: [] } as { groups: Group[] };
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.groups = [
|
||||||
|
{
|
||||||
|
label: t`Global`,
|
||||||
|
description: t`Applicable anywhere in Frappe Books`,
|
||||||
|
collapsed: false,
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, 'K'],
|
||||||
|
description: t`Open Quick Search`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.del],
|
||||||
|
description: t`Go back to the previous page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.shift, 'H'],
|
||||||
|
description: t`Toggle sidebar`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: ['F1'],
|
||||||
|
description: t`Open Documentation`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t`Doc`,
|
||||||
|
description: t`Applicable when a Doc is open in the Form view or Quick Edit view`,
|
||||||
|
collapsed: false,
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, 'S'],
|
||||||
|
description: [
|
||||||
|
t`Save or Submit a doc.`,
|
||||||
|
t`A doc is submitted only if it is submittable and is in the saved state.`,
|
||||||
|
].join(' '),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, this.del],
|
||||||
|
description: [
|
||||||
|
t`Cancel or Delete a doc.`,
|
||||||
|
t`A doc is cancelled only if it is in the submitted state.`,
|
||||||
|
t`A submittable doc is deleted only if it is in the cancelled state.`,
|
||||||
|
].join(' '),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t`Quick Search`,
|
||||||
|
description: t`Applicable when Quick Search is open`,
|
||||||
|
collapsed: false,
|
||||||
|
shortcuts: [
|
||||||
|
{ shortcut: [this.esc], description: t`Close Quick Search` },
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, '1'],
|
||||||
|
description: t`Toggle the Docs filter`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, '2'],
|
||||||
|
description: t`Toggle the List filter`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, '3'],
|
||||||
|
description: t`Toggle the Create filter`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, '4'],
|
||||||
|
description: t`Toggle the Report filter`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shortcut: [this.pmod, '5'],
|
||||||
|
description: t`Toggle the Page filter`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pmod() {
|
||||||
|
if (this.isMac) {
|
||||||
|
return '⌘';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Ctrl';
|
||||||
|
},
|
||||||
|
shift() {
|
||||||
|
if (this.isMac) {
|
||||||
|
return 'shift';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '⇧';
|
||||||
|
},
|
||||||
|
alt() {
|
||||||
|
if (this.isMac) {
|
||||||
|
return '⌥';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Alt';
|
||||||
|
},
|
||||||
|
del() {
|
||||||
|
if (this.isMac) {
|
||||||
|
return 'delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Backspace';
|
||||||
|
},
|
||||||
|
esc() {
|
||||||
|
if (this.isMac) {
|
||||||
|
return 'esc';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Esc';
|
||||||
|
},
|
||||||
|
isMac() {
|
||||||
|
return this.platform === 'Mac';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: { FormHeader },
|
||||||
|
});
|
||||||
|
</script>
|
@ -100,6 +100,20 @@
|
|||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="
|
||||||
|
flex
|
||||||
|
text-sm text-gray-600
|
||||||
|
hover:text-gray-800
|
||||||
|
gap-1
|
||||||
|
items-center
|
||||||
|
"
|
||||||
|
@click="viewShortcuts = true"
|
||||||
|
>
|
||||||
|
<feather-icon name="command" class="h-4 w-4 flex-shrink-0" />
|
||||||
|
<p>{{ t`Shortcuts` }}</p>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="
|
class="
|
||||||
flex
|
flex
|
||||||
@ -155,6 +169,10 @@
|
|||||||
>
|
>
|
||||||
<feather-icon name="chevrons-left" class="w-4 h-4" />
|
<feather-icon name="chevrons-left" class="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<Modal :open-modal="viewShortcuts" @closemodal="viewShortcuts = false">
|
||||||
|
<ShortcutsHelper class="w-form" />
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -167,15 +185,18 @@ import { getSidebarConfig } from 'src/utils/sidebarConfig';
|
|||||||
import { routeTo } from 'src/utils/ui';
|
import { routeTo } from 'src/utils/ui';
|
||||||
import router from '../router';
|
import router from '../router';
|
||||||
import Icon from './Icon.vue';
|
import Icon from './Icon.vue';
|
||||||
|
import Modal from './Modal.vue';
|
||||||
|
import ShortcutsHelper from './ShortcutsHelper.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: [Button],
|
components: [Button],
|
||||||
inject: ['languageDirection'],
|
inject: ['languageDirection', 'shortcuts'],
|
||||||
emits: ['change-db-file', 'toggle-sidebar'],
|
emits: ['change-db-file', 'toggle-sidebar'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
companyName: '',
|
companyName: '',
|
||||||
groups: [],
|
groups: [],
|
||||||
|
viewShortcuts: false,
|
||||||
activeGroup: null,
|
activeGroup: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -186,6 +207,8 @@ export default {
|
|||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Icon,
|
Icon,
|
||||||
|
Modal,
|
||||||
|
ShortcutsHelper,
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
const { companyName } = await fyo.doc.getDoc('AccountingSettings');
|
const { companyName } = await fyo.doc.getDoc('AccountingSettings');
|
||||||
@ -196,6 +219,17 @@ export default {
|
|||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
this.setActiveGroup();
|
this.setActiveGroup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.shortcuts.shift.set(['KeyH'], () => {
|
||||||
|
if (document.body === document.activeElement) {
|
||||||
|
this.$emit('toggle-sidebar');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.shortcuts.set(['F1'], () => this.openDocumentation());
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
this.shortcuts.alt.delete(['KeyH']);
|
||||||
|
this.shortcuts.delete(['F1']);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
routeTo,
|
routeTo,
|
||||||
|
@ -144,7 +144,7 @@ export function useKeys() {
|
|||||||
const { code } = e;
|
const { code } = e;
|
||||||
if (
|
if (
|
||||||
code.startsWith('Alt') ||
|
code.startsWith('Alt') ||
|
||||||
code.startsWith('Ctrl') ||
|
code.startsWith('Control') ||
|
||||||
code.startsWith('Meta') ||
|
code.startsWith('Meta') ||
|
||||||
code.startsWith('Shift')
|
code.startsWith('Shift')
|
||||||
) {
|
) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user