Skip to content

Commit

Permalink
move signalr&ipc code to vuex
Browse files Browse the repository at this point in the history
  • Loading branch information
iwate committed Apr 28, 2020
1 parent bb68729 commit e60a764
Show file tree
Hide file tree
Showing 24 changed files with 731 additions and 620 deletions.
7 changes: 4 additions & 3 deletions src/Aiplugs.PoshApp/Services/Git/GitWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,14 @@ public void Clone(CloneCommand cmd)
CredentialsProvider = new LibGit2Sharp.Handlers.CredentialsHandler(GetCredential)
});
}
catch(Exception)
catch (Exception ex)
{
if (_credentials.ContainsKey(cmd.Origin)) {
if (_credentials.ContainsKey(cmd.Origin))
{
_credentials.Remove(cmd.Origin);
}
Client.SendAsync("GitCloneFaild", cmd.Name).Wait();
throw;
throw ex;
}

Client.SendAsync("GitClone", cmd.Name).Wait();
Expand Down
2 changes: 1 addition & 1 deletion src/Aiplugs.PoshApp/Services/ScriptsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ScriptsService
[ScriptType.List] = "param(\n\t[int]\n\t$Page,\n\n\t[int]\n\t$PageSize\n)\n",
[ScriptType.Detail] = "param(\n\t[Parameter(ValueFromPipeline=$true,Mandatory=$true)]\n\t[PSObject]\n\t$InputObject\n)\n",
[ScriptType.Singleton] = "",
[ScriptType.Action] = "param(\n\t[Parameter(ValueFromPipeline=$true)]\n\t[PSObject[]]\n\t$InputObject\n)\nprocess {\n\n}"
[ScriptType.Action] = "param(\n\t[Parameter(ValueFromPipeline=$true)]\n\t[PSObject[]]\n\t$InputObject\n)\n"
};
private readonly ConfigAccessor _configAccessor;
private readonly LicenseService _license;
Expand Down
13 changes: 8 additions & 5 deletions src/Aiplugs.PoshApp/Views/Shared/App.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,17 @@
</v-app>
</template>
<script>
function checkForUpdates() {
ipcRenderer.send('check-for-updates');
setTimeout(checkForUpdates, 60 * 60 * 1000);
}
Vue.component('App', {
template: "#app-component",
methods: {
...Vuex.mapActions('ipc', ['checkForUpdates']),
},
mounted() {
checkForUpdates();
const update = () => {
this.checkForUpdates();
};
setTimeout(update, 60 * 60 * 1000);
update();
}
})
</script>
22 changes: 7 additions & 15 deletions src/Aiplugs.PoshApp/Views/Shared/Components/UpdateNotice.cshtml
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
<template id="update-notice-component">
<v-dialog v-model="dialog" max-width="600">
<v-dialog :value="updateAvailable" max-width="600" persistent>
<v-card>
<v-card-title>New version is released!</v-card-title>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text v-on:click="dialog=false">At later</v-btn>
<v-btn color="primary" v-on:click="install">Quit and Install now</v-btn>
<v-btn text v-on:click="clearUpdateAvailable">At later</v-btn>
<v-btn color="primary" v-on:click="quitAndInstall">Quit and Install now</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
Vue.component('updatenotice', {
template: '#update-notice-component',
data() {
return {
dialog: false
}
computed: {
...Vuex.mapState('ipc', ['updateAvailable'])
},
methods: {
install() {
ipcRenderer.send('quit-and-install');
}
},
mounted() {
ipcRenderer.on('update-available', (sender) => {
this.dialog = true;
});
...Vuex.mapMutations('ipc', ['clearUpdateAvailable']),
...Vuex.mapActions('ipc', ['quitAndInstall'])
}
})
</script>
11 changes: 1 addition & 10 deletions src/Aiplugs.PoshApp/Views/Shared/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,7 @@
{
<script>
const { ipcRenderer } = require("electron");
</script>
}
else
{
<script>
const ipcRenderer = {
on: function() {},
send: function() {},
removeAllListeners: function() {},
}
window.ipcRenderer = ipcRenderer;
</script>
}
<partial name="Components/ActivationNotice" />
Expand Down
29 changes: 8 additions & 21 deletions src/Aiplugs.PoshApp/Views/Shared/Pages/Detail.cshtml
Original file line number Diff line number Diff line change
@@ -1,46 +1,33 @@
<template id="detail-page">
<section v-if="data" class="d-flex flex-column white" style="position: absolute; top:0; width:calc(100vw - 56px - 256px); height: calc(100vh - 24px); overflow:hidden;">
<section v-if="detailResult" class="d-flex flex-column white" style="position: absolute; top:0; width:calc(100vw - 56px - 256px); height: calc(100vh - 24px); overflow:hidden;">
<header>
<v-btn text v-on:click="$emit('close')">
<v-icon>mdi-arrow-right</v-icon>
</v-btn>
<v-btn text v-for="action in actions" :key="action.id" v-on:click="invokeAction(action.id)">{{action.displayName || action.id}}</v-btn>
<v-btn text v-for="action in actions" :key="action.id" v-on:click="invokeAction({scriptId:action.id, input:[input]})">{{action.displayName || action.id}}</v-btn>
</header>
<div class="flex scroll-content">
<data-viewer :data="data"></data-viewer>
<data-viewer :data="detailResult"></data-viewer>
</div>
</section>
</template>

<script type="module">
import { parsePSDataCollection } from '/js/clixml.js'
<script>
Vue.component('detail-page', {
template: '#detail-page',
props: ['script', 'input'],
data() {
return {
data: null
}
},
computed: {
...Vuex.mapState('signalr', ['detailResult']),
actions() {
const [repo, id] = this.script.split(':');
return this.$store.getters['scripts/findActions'](repo, id);
}
},
methods:{
invokeAction(name) {
this.$signalr.invoke('InvokeAction', name, null);
}
methods: {
...Vuex.mapActions('signalr', ['invokeDetail', 'invokeAction'])
},
mounted() {
this.$signalr.on('DetailResult', json => {
this.data = parsePSDataCollection(JSON.parse(json));
})
this.$signalr.invoke('InvokeDetail', this.script, this.input);
},
beforeDestroy() {
this.$signalr.off('DetailResult')
this.invokeDetail({ scriptId: this.script, input: this.input });
}
})
</script>
141 changes: 59 additions & 82 deletions src/Aiplugs.PoshApp/Views/Shared/Pages/List.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,46 @@
<header>
<v-row class="pl-4 pr-4" style="width: 100%;">
<v-col cols="12" class="pt-0 pb-0">
<parameters-form ref="form" :script="scriptId" :page="page" :page-size="pageSize" :loading="loading=='$run'" :disabled="disabled" v-on:run="run"></parameters-form>
<parameters-form ref="form"
:script="scriptId"
:page="page"
:page-size="pageSize"
:loading="invoking=='$default'"
:disabled="disabled"
v-on:run="run">
</parameters-form>
</v-col>
</v-row>
<v-row class="pl-4 pr-4">
<v-btn text v-for="action in actions" :key="action.name" :loading="loading==action.id" :disabled="disabled" v-on:click="invokeAction(action.id)" retain-focus-on-click>{{action.displayName || action.id}}</v-btn>
<v-btn text v-for="action in actions"
:key="action.name"
:loading="invoking==action.id"
:disabled="disabled"
v-on:click="invokeAction({ scriptId:action.id, input: selected.map(item => item.$clixml) })"
retain-focus-on-click>{{action.displayName || action.id}}</v-btn>
</v-row>
</header>
<v-divider></v-divider>
<div class="flex scroll-content">
<v-data-table v-model="selected"
:headers="headers"
:items="list"
:headers="view.headers"
:items="view.list"
:page.sync="page"
:items-per-page="pageSize"
item-key="$clixml"
hide-default-footer
show-select
v-if="list.length > 0">
v-if="view.list.length > 0">
<template v-slot:item.$poshapp_action="{ item }">
<v-btn icon text v-on:click="openDetail(item)">
<v-icon>mdi-fullscreen</v-icon>
</v-btn>
</template>
</v-data-table>
</div>
<div class="text-center overline" v-if="view.list.length > 0">Total {{view.total}}</div>
<div class="ma-auto" style="width: 80%;">
<v-pagination v-model="page" :length="total" v-if="list.length > 0"></v-pagination>
<v-pagination v-model="page" :length="view.pageCount" v-if="view.list.length > 0"></v-pagination>
</div>
<transition name="slide-x-reverse-transition">
<detail-page :script="detailScriptId" :input="detailInput" v-if="detailScriptId" v-on:close="detailScriptId=null"></detail-page>
Expand All @@ -39,24 +52,20 @@
</v-btn>
</div>
</template>
<script type="module">
import { parsePSDataCollection, createCliXml } from '/js/clixml.js'
<script>
Vue.component('ListPage', {
template: '#list-page-component',
data() {
return {
selected:[],
detailScriptId: null,
detailInput: null,
detailInput: null,
page: 1,
pageSize: 10,
total: 0,
list: [],
headers: [],
loading: null,
}
},
computed: {
...Vuex.mapState('signalr', ['invoking','defaultResult']),
scriptId() {
return `${this.$route.params.repo}:${this.$route.params.id}`;
},
Expand All @@ -69,79 +78,53 @@
return this.$store.getters['scripts/findActions'](repo, id);
},
disabled() {
return !!this.loading
}
},
methods: {
...Vuex.mapActions('toast', ['toast']),
...Vuex.mapMutations('list', ['updateList','replaceData','setDetail']),
init() {
this.selected.splice(0);
this.list.splice(0);
this.headers.splice(0);
this.total = 0;
this.$signalr.on("DefaultResult", json => {
this.loading = null;
const data = parsePSDataCollection(JSON.parse(json));
if (data.length == 0)
return;
let index = 0;
let total = data.length;
const pageSize = this.pageSize - 0;
return !!this.invoking
},
view() {
const data = this.defaultResult;
if (data == null) {
return { list: [], headers:[], total: 0 }
}
if (typeof data[index].value === 'number') {
total = data[index].value;
index++;
}
let index = 0;
let total = data.length;
if (typeof data[index].value === 'number') {
total = data[index].value;
index++;
}
const pageCount = ~~(total / pageSize) + Math.min(1, total % pageSize);
const pageCount = ~~(total / this.pageSize) + Math.min(1, total % this.pageSize);
const dataset = data.slice(index);
const dataset = data.slice(index);
const allKeys = Object.keys(dataset.reduce((o,d) => Object.assign(o,d.value),{}));
const allKeys = Object.keys(dataset.reduce((o,d) => Object.assign(o,d.value), {}));
const headers = allKeys.map(key => ({ text:key, value:key, sortable: false }));
const headers = allKeys.map(key => ({ text:key, value:key, sortable: false }));
if (this.detailId) {
headers.unshift({text: '', value: '$poshapp_action', width: 64, sortable: false });
}
if (this.detailId) {
headers.unshift({text: '', value: '$poshapp_action', width: 64, sortable: false });
}
this.pageSize = this.$refs.form.getPageSize();
this.total = pageCount;
this.headers.splice(0, this.headers.length, ...headers);
this.list.splice(0, this.list.length, ...dataset.filter(d => typeof d.value == 'object').map(d => {
d.value.$clixml = d.clixml;
return d.value;
}));
})
this.$signalr.on("ActionResult", (id, json) => {
this.loading = null;
const data = JSON.parse(json);
this.toast({
text: `${id} is succeeded` ,
color: "info",
top: true,
right: true
});
})
this.$signalr.on('UnitResult', () => {
this.loading = null;
})
},
run(value) {
this.loading = '$run';
this.$signalr.invoke('Invoke', this.scriptId, value);
const list = dataset.filter(d => typeof d.value == 'object').map(d => {
return Object.assign({ $clixml: d.clixml }, d.value);
});
return { list, headers, total, pageCount };
}
},
methods: {
...Vuex.mapActions('signalr', ['invokeDefault', 'invokeAction', 'clearResult']),
init() {
this.clearResult();
this.selected.splice(0);
},
invokeAction(id) {
this.loading = id;
this.$signalr.invoke('InvokeAction', id, this.selected.map(item => item.$clixml));
run({ value, page, pageSize }) {
this.invokeDefault({ scriptId: this.scriptId, input: value });
this.page = page;
this.pageSize = pageSize;
},
openDetail(item) {
const clixml = item.$clixml;
this.detailInput = clixml;
this.detailInput = item.$clixml;
this.detailScriptId = this.detailId;
},
gotoEditor() {
Expand All @@ -160,12 +143,6 @@
beforeRouteUpdate (to, from, next) {
this.init();
next();
},
beforeRouteLeave (to, from , next) {
this.$signalr.off('DefaultResult');
this.$signalr.off('ActionResult');
this.$signalr.off('UnitResult');
next();
}
})
</script>
Loading

0 comments on commit e60a764

Please sign in to comment.