From 0a66679bb92c75a4f26480f43d122db3b010cc9e Mon Sep 17 00:00:00 2001 From: phil294 Date: Mon, 1 May 2023 00:18:50 +0200 Subject: [PATCH] make branch actions available via context menu too --- .vscode/settings.json | 3 + web/src/App.vue | 15 ++++ web/src/directives/context-menu.coffee | 95 ++++++++++++++++++++++++++ web/src/views/CommitDetails.coffee | 14 ++-- web/src/views/CommitDetails.vue | 8 +-- web/src/views/GitActionButton.coffee | 22 ++---- web/src/views/GitActionButton.vue | 20 ++---- web/src/views/MainView.coffee | 9 +-- web/src/views/MainView.vue | 10 +-- web/src/views/RefTip.coffee | 20 +++++- web/src/views/RefTip.vue | 2 +- web/src/views/SelectedGitAction.coffee | 19 ++++++ web/src/views/SelectedGitAction.vue | 15 ++++ web/src/views/Visualization.vue | 2 +- web/src/views/store.coffee | 28 ++++++-- web/src/views/types.coffee | 1 + web/src/vue-app.coffee | 2 + 17 files changed, 220 insertions(+), 65 deletions(-) create mode 100644 web/src/directives/context-menu.coffee create mode 100644 web/src/views/SelectedGitAction.coffee create mode 100644 web/src/views/SelectedGitAction.vue diff --git a/.vscode/settings.json b/.vscode/settings.json index bb80dd4..322455d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,10 +24,13 @@ "**/.git/**" ], "cSpell.words": [ + "codicon", "datetime", "mhutchie", "numstat", "oneline", + "onglobalclick", + "onglobalkeyup", "reflog", "scroller", "shortstat" diff --git a/web/src/App.vue b/web/src/App.vue index d639a04..b8c258c 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -203,6 +203,21 @@ input:not([type='checkbox']):not([type='radio']).filter padding 0 0 0 5px background black color #d5983d + +ul.context-menu-wrapper + position absolute + background #111111dd + min-width 150px + cursor pointer + box-shadow 0 2px 3px 2px #111111dd + user-select none + z-index 10 + > li + padding 4px 8px + &:not(:last-child) + border-bottom 1px solid #424242 + &:hover + background black \ No newline at end of file diff --git a/web/src/views/MainView.coffee b/web/src/views/MainView.coffee index 3ccf903..55d9b91 100644 --- a/web/src/views/MainView.coffee +++ b/web/src/views/MainView.coffee @@ -7,6 +7,7 @@ import GitActionButton from './GitActionButton.vue' import CommitDetails from './CommitDetails.vue' import Visualization from './Visualization.vue' import AllBranches from './AllBranches.vue' +import SelectedGitAction from './SelectedGitAction.vue' import RefTip from './RefTip.vue' ``###* # @typedef {import('./types').Commit} Commit @@ -23,7 +24,7 @@ import RefTip from './RefTip.vue' is_truthy = (value) => !!value export default - components: { CommitDetails, GitInput, GitActionButton, Visualization, AllBranches, RefTip } + components: { CommitDetails, GitInput, GitActionButton, Visualization, AllBranches, RefTip, SelectedGitAction } setup: -> @@ -91,8 +92,7 @@ export default ``###* @type {Ref} ### git_input_ref = ref null - do_log = => - git_input_ref.value?.execute() + store.main_view_git_input_ref.value = git_input_ref log_action = # rearding the -greps: Under normal circumstances, when showing stashes in # git log, each of the stashes 2 or 3 parents are being shown. That because of @@ -237,7 +237,6 @@ export default head_branch: store.head_branch git_input_ref run_log - do_log log_action commits_scroller_updated visible_branches @@ -257,4 +256,6 @@ export default invisible_branch_tips_of_visible_branches_elems connection_fake_commit escape_pressed + refresh_main_view: store.refresh_main_view + selected_git_action: store.selected_git_action } \ No newline at end of file diff --git a/web/src/views/MainView.vue b/web/src/views/MainView.vue index edf39e9..15a97f8 100644 --- a/web/src/views/MainView.vue +++ b/web/src/views/MainView.vue @@ -22,8 +22,8 @@ input type="radio" v-model="txt_filter_type" value="search" | Search section#actions.center.gap-5 aria-roledescription="Global actions" - git-action-button.global-action v-for="action of global_actions" :git_action="action" @change="do_log()" - button#refresh.btn.center @click="do_log()" title="Refresh" + git-action-button.global-action v-for="action of global_actions" :git_action="action" + button#refresh.btn.center @click="refresh_main_view()" title="Refresh" i.codicon.codicon-refresh #quick-branch-tips all-branches @branch_selected="scroll_to_branch_tip($event)" @@ -51,7 +51,7 @@ progress.diff v-if="commit.stats" :value="(commit.stats.insertions / (commit.stats.insertions + commit.stats.deletions)) || 0" title="Ratio insertions / deletions" .datetime.flex-noshrink {{ commit.datetime }} #right.col.flex-1 v-if="selected_commit" - commit-details#selected-commit.flex-1.fill-w.padding :commit="selected_commit" @change="do_log()" + commit-details#selected-commit.flex-1.fill-w.padding :commit="selected_commit" button#close-selected-commit.center @click="selected_commit=null" title="Close" i.codicon.codicon-close #resize-hint v-if="selected_commit" @@ -59,7 +59,9 @@ popup v-if="combine_branches_from_branch_name" @close="combine_branches_from_branch_name=''" .drag-drop-branch-actions.col.center.gap-5 - git-action-button.drag-drop-branch-action v-for="action of combine_branches_actions" :git_action="action" @change="do_log()" + git-action-button.drag-drop-branch-action v-for="action of combine_branches_actions" :git_action="action" + popup v-if="selected_git_action" @close="selected_git_action=null" + selected-git-action diff --git a/web/src/views/RefTip.coffee b/web/src/views/RefTip.coffee index 48850ff..713e1a4 100644 --- a/web/src/views/RefTip.coffee +++ b/web/src/views/RefTip.coffee @@ -1,6 +1,8 @@ import { defineComponent, computed } from 'vue' -import { head_branch, combine_branches } from './store.coffee' +import { head_branch, combine_branches, branch_actions, stash_actions, selected_git_action } from './store.coffee' ``###* @typedef {import('./types').GitRef} GitRef ### +``###* @typedef {import('./types').Commit} Commit ### +``###* @typedef {import('./types').GitAction} GitAction ### export default defineComponent props: @@ -8,9 +10,18 @@ export default defineComponent required: true ###* @type {() => GitRef} ### type: Object + commit: + ###* @type {() => Commit} ### + type: Object setup: (props) -> is_branch = computed => props.git_ref.type == 'branch' + to_context_menu_entries = (###* @type GitAction[] ### actions) => + actions.map (action) => + label: action.title + icon: action.icon + action: => + selected_git_action.value = action bind: computed => style: color: props.git_ref.color @@ -23,4 +34,9 @@ export default defineComponent return if not is_branch.value source_branch_name = event.data return if typeof source_branch_name != 'string' - combine_branches(source_branch_name, props.git_ref.name) \ No newline at end of file + combine_branches(source_branch_name, props.git_ref.name) + context_menu: + if is_branch.value + to_context_menu_entries(branch_actions(props.git_ref.name)) + else if props.git_ref.type == 'stash' and props.commit + to_context_menu_entries(stash_actions(props.commit.hash)) \ No newline at end of file diff --git a/web/src/views/RefTip.vue b/web/src/views/RefTip.vue index c487e1f..87ccf25 100644 --- a/web/src/views/RefTip.vue +++ b/web/src/views/RefTip.vue @@ -1,5 +1,5 @@ diff --git a/web/src/views/SelectedGitAction.coffee b/web/src/views/SelectedGitAction.coffee new file mode 100644 index 0000000..fb6f22f --- /dev/null +++ b/web/src/views/SelectedGitAction.coffee @@ -0,0 +1,19 @@ +import { ref, defineComponent } from 'vue' +import { selected_git_action, refresh_main_view } from './store.coffee' +import GitInput from './GitInput.vue' + +export default defineComponent + components: { GitInput } + setup: -> + keep_open = ref false + + success = => + if not keep_open.value + selected_git_action.value = null + refresh_main_view() + + { + keep_open + success + selected_git_action + } \ No newline at end of file diff --git a/web/src/views/SelectedGitAction.vue b/web/src/views/SelectedGitAction.vue new file mode 100644 index 0000000..c027c57 --- /dev/null +++ b/web/src/views/SelectedGitAction.vue @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/Visualization.vue b/web/src/views/Visualization.vue index 9acc7be..f489bea 100644 --- a/web/src/views/Visualization.vue +++ b/web/src/views/Visualization.vue @@ -4,7 +4,7 @@ line.vis-v v-for="line of lines" v-bind="line" circle.vis-v v-if="circle" v-bind="circle" .refs.row.align-center :style="refs_elems.style" - ref-tip v-for="ref of refs_elems.refs" :git_ref="ref" + ref-tip v-for="ref of refs_elems.refs" :git_ref="ref" :commit="commit" diff --git a/web/src/views/store.coffee b/web/src/views/store.coffee index 48b1ab2..6e2f24f 100644 --- a/web/src/views/store.coffee +++ b/web/src/views/store.coffee @@ -1,6 +1,7 @@ import { parse_config_actions } from "./GitInput.coffee" import { parse } from "./log-utils.coffee" import { git, get_config } from "../bridge.coffee" +import GitInputModel from './GitInput.coffee' import { ref, computed } from "vue" ``###* # @typedef {import('./types').GitRef} GitRef @@ -8,6 +9,7 @@ import { ref, computed } from "vue" # @typedef {import('./types').Vis} Vis # @typedef {import('./types').Commit} Commit # @typedef {import('./types').ConfigGitAction} ConfigGitAction +# @typedef {import('./types').GitAction} GitAction ### ###* @template T @typedef {import('vue').Ref} Ref ### ###* @template T @typedef {import('vue').ComputedRef} ComputedRef ### @@ -53,6 +55,11 @@ export git_run_log = (###* @type string ### log_args) => # todo rename to vis_max_amount vis_max_length.value = parsed.vis_max_length head_branch.value = await git 'rev-parse --abbrev-ref HEAD' +``###* @type {Ref|null>} ### +export main_view_git_input_ref = ref null +export refresh_main_view = => + console.info('refreshing main view') + main_view_git_input_ref.value?.value?.execute() export update_commit_stats = (###* @type {Commit[]} ### commits) => data = await git "show --format=\"%h\" --shortstat " + commits.map((c)=>c.hash).join(' ') @@ -77,11 +84,17 @@ export update_commit_stats = (###* @type {Commit[]} ### commits) => ``###* @type {Ref} ### export global_actions = ref [] ``###* @type {Ref} ### -export branch_actions = ref [] +config_branch_actions = ref [] +export commit_actions = (###* @type string ### hash) => + parse_config_actions(config_commit_actions.value, [['{COMMIT_HASH}', hash]]) ``###* @type {Ref} ### -export commit_actions = ref [] +config_commit_actions = ref [] +export branch_actions = (###* @type string ### branch_name) => + parse_config_actions(config_branch_actions.value, [['{BRANCH_NAME}', branch_name]]) ``###* @type {Ref} ### -export stash_actions = ref [] +config_stash_actions = ref [] +export stash_actions = (###* @type string ### hash) => + parse_config_actions(config_stash_actions.value, [['{COMMIT_HASH}', hash]]) ``###* @type {Ref} ### _unparsed_combine_branches_actions = ref [] export combine_branches_actions = computed => @@ -96,6 +109,9 @@ export combine_branches = (###* @type string ### from_branch_name, ###* @type st combine_branches_to_branch_name.value = to_branch_name combine_branches_from_branch_name.value = from_branch_name +``###* @type {Ref} ### +export selected_git_action = ref null + ``###* @type {Ref} ### export selected_commit = ref null @@ -106,9 +122,9 @@ export init = => refresh_config() export refresh_config = => global_actions.value = await get_config 'actions.global' - branch_actions.value = await get_config 'actions.branch' - commit_actions.value = await get_config 'actions.commit' - stash_actions.value = await get_config 'actions.stash' + config_branch_actions.value = await get_config 'actions.branch' + config_commit_actions.value = await get_config 'actions.commit' + config_stash_actions.value = await get_config 'actions.stash' _unparsed_combine_branches_actions.value = await get_config 'actions.branch-drop' diff --git a/web/src/views/types.coffee b/web/src/views/types.coffee index 9cc293f..d0ba0fa 100644 --- a/web/src/views/types.coffee +++ b/web/src/views/types.coffee @@ -48,6 +48,7 @@ import colors from "./colors.coffee" # args: string # params?: string[] # options?: GitOption[] +# icon?: string # }} ConfigGitAction # # @typedef {ConfigGitAction & { diff --git a/web/src/vue-app.coffee b/web/src/vue-app.coffee index a69a94a..ab035ef 100644 --- a/web/src/vue-app.coffee +++ b/web/src/vue-app.coffee @@ -6,6 +6,7 @@ import Popup from './components/Popup.vue' import moveable from './directives/moveable' import drag from './directives/drag' import drop from './directives/drop' +import context_menu from './directives/context-menu' import { RecycleScroller } from 'vue-virtual-scroller' import 'vue-virtual-scroller/dist/vue-virtual-scroller.css' import '@vscode/codicons/dist/codicon.css' @@ -32,5 +33,6 @@ app.component 'recycle-scroller', RecycleScroller app.directive 'moveable', moveable app.directive 'drag', drag app.directive 'drop', drop +app.directive 'context-menu', context_menu app.mount('#app') \ No newline at end of file