feat:アクション選択UI改善
This commit is contained in:
@@ -5,8 +5,10 @@ import base64
|
|||||||
PROJECT_NAME = "KintoneAppBuilder"
|
PROJECT_NAME = "KintoneAppBuilder"
|
||||||
|
|
||||||
#SQLALCHEMY_DATABASE_URI = "postgres://maxz64:m@xz1205@alicornkintone.postgres.database.azure.com/postgres"
|
#SQLALCHEMY_DATABASE_URI = "postgres://maxz64:m@xz1205@alicornkintone.postgres.database.azure.com/postgres"
|
||||||
SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/postgres"
|
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/postgres"
|
||||||
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/unittest"
|
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/unittest"
|
||||||
|
SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/dev"
|
||||||
|
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@ktune-prod-db.postgres.database.azure.com/postgres"
|
||||||
API_V1_STR = "/k/v1"
|
API_V1_STR = "/k/v1"
|
||||||
|
|
||||||
API_V1_AUTH_KEY = "X-Cybozu-Authorization"
|
API_V1_AUTH_KEY = "X-Cybozu-Authorization"
|
||||||
|
|||||||
@@ -281,9 +281,35 @@ def get_events(db: Session):
|
|||||||
raise HTTPException(status_code=404, detail="Data not found")
|
raise HTTPException(status_code=404, detail="Data not found")
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
def get_category(db:Session):
|
||||||
|
categorys=db.query(models.Category).all()
|
||||||
|
return categorys
|
||||||
|
|
||||||
def get_eventactions(db: Session,eventid: str):
|
def get_eventactions(db: Session,eventid: str):
|
||||||
#eveactions = db.query(models.Action).join(models.EventAction,models.EventAction.actionid == models.Action.id ).join(models.Event,models.Event.id == models.EventAction.eventid).filter(models.Event.eventid == eventid).all()
|
#eveactions = db.query(models.Action).join(models.EventAction,models.EventAction.actionid == models.Action.id ).join(models.Event,models.Event.id == models.EventAction.eventid).filter(models.Event.eventid == eventid).all()
|
||||||
eveactions = db.query(models.Action).join(models.EventAction,models.EventAction.actionid != models.Action.id and models.EventAction.eventid == eventid ).join(models.Event,models.Event.id == models.EventAction.eventid).filter(models.Event.eventid == eventid).all()
|
#category = get_category(db)
|
||||||
|
blackactions = (
|
||||||
|
db.query(models.EventAction.actionid)
|
||||||
|
.filter(models.EventAction.eventid == eventid)
|
||||||
|
.subquery()
|
||||||
|
)
|
||||||
|
eveactions = (
|
||||||
|
db.query(
|
||||||
|
models.Action.id,
|
||||||
|
models.Action.name,
|
||||||
|
models.Action.title,
|
||||||
|
models.Action.subtitle,
|
||||||
|
models.Action.outputpoints,
|
||||||
|
models.Action.property,
|
||||||
|
models.Action.categoryid,
|
||||||
|
models.Action.nosort,
|
||||||
|
models.Category.categoryname)
|
||||||
|
.join(models.Category,models.Category.id == models.Action.categoryid)
|
||||||
|
.filter(models.Action.id.notin_(blackactions))
|
||||||
|
.order_by(models.Category.nosort,models.Action.nosort)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
if not eveactions:
|
if not eveactions:
|
||||||
raise HTTPException(status_code=404, detail="Data not found")
|
raise HTTPException(status_code=404, detail="Data not found")
|
||||||
return eveactions
|
return eveactions
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class Action(Base):
|
|||||||
subtitle = Column(String(500))
|
subtitle = Column(String(500))
|
||||||
outputpoints = Column(String)
|
outputpoints = Column(String)
|
||||||
property = Column(String)
|
property = Column(String)
|
||||||
|
categoryid = Column(Integer,ForeignKey("category.id"))
|
||||||
|
nosort = Column(Integer)
|
||||||
|
|
||||||
class Flow(Base):
|
class Flow(Base):
|
||||||
__tablename__ = "flow"
|
__tablename__ = "flow"
|
||||||
@@ -95,7 +97,7 @@ class Event(Base):
|
|||||||
class EventAction(Base):
|
class EventAction(Base):
|
||||||
__tablename__ = "eventaction"
|
__tablename__ = "eventaction"
|
||||||
|
|
||||||
eventid = Column(Integer,ForeignKey("event.id"))
|
eventid = Column(String(100),ForeignKey("event.eventid"))
|
||||||
actionid = Column(Integer,ForeignKey("action.id"))
|
actionid = Column(Integer,ForeignKey("action.id"))
|
||||||
|
|
||||||
|
|
||||||
@@ -115,4 +117,10 @@ class KintoneFormat(Base):
|
|||||||
typecolumn =Column(Integer)
|
typecolumn =Column(Integer)
|
||||||
codecolumn =Column(Integer)
|
codecolumn =Column(Integer)
|
||||||
field = Column(String(5000))
|
field = Column(String(5000))
|
||||||
trueformat = Column(String(10))
|
trueformat = Column(String(10))
|
||||||
|
|
||||||
|
class Category(Base):
|
||||||
|
__tablename__ = "category"
|
||||||
|
|
||||||
|
categoryname = Column(String(20))
|
||||||
|
nosort = Column(Integer)
|
||||||
@@ -89,7 +89,9 @@ class Action(BaseModel):
|
|||||||
subtitle: str = None
|
subtitle: str = None
|
||||||
outputpoints: str = None
|
outputpoints: str = None
|
||||||
property: str = None
|
property: str = None
|
||||||
|
categoryid: int = None
|
||||||
|
nosort: int
|
||||||
|
categoryname : str =None
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,46 @@
|
|||||||
<div v-if="!isLoaded" class="spinner flex flex-center">
|
<div v-if="!isLoaded" class="spinner flex flex-center">
|
||||||
<q-spinner color="primary" size="3em" />
|
<q-spinner color="primary" size="3em" />
|
||||||
</div>
|
</div>
|
||||||
<q-table v-else row-key="index" :selection="type" v-model:selected="selected" :columns="columns" :rows="rows"
|
<q-splitter
|
||||||
class="action-table"
|
v-model="splitterModel"
|
||||||
flat bordered
|
style="height: 100%"
|
||||||
virtual-scroll
|
before-class="tab"
|
||||||
:pagination="pagination"
|
unit="px"
|
||||||
:rows-per-page-options="[0]"
|
v-else
|
||||||
:filter="filter"
|
|
||||||
>
|
>
|
||||||
</q-table>
|
<template v-slot:before>
|
||||||
|
<q-tabs
|
||||||
|
v-model="tab"
|
||||||
|
vertical
|
||||||
|
active-color="white"
|
||||||
|
indicator-color="primary"
|
||||||
|
active-bg-color="primary"
|
||||||
|
class="bg-grey-2 text-grey-8"
|
||||||
|
dense
|
||||||
|
>
|
||||||
|
<q-tab :name="cate"
|
||||||
|
:label="cate"
|
||||||
|
v-for="(cate,) in categorys"
|
||||||
|
:key="cate"
|
||||||
|
></q-tab>
|
||||||
|
</q-tabs>
|
||||||
|
</template>
|
||||||
|
<template v-slot:after>
|
||||||
|
<q-table row-key="index" :selection="type" v-model:selected="selected" :columns="columns" :rows="actionForTab"
|
||||||
|
class="action-table"
|
||||||
|
flat bordered
|
||||||
|
virtual-scroll
|
||||||
|
:pagination="pagination"
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
:filter="filter"></q-table>
|
||||||
|
</template>
|
||||||
|
</q-splitter>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ref,onMounted,reactive } from 'vue'
|
import { ref,onMounted,reactive,watchEffect,computed,watch } from 'vue'
|
||||||
import { api } from 'boot/axios';
|
import { api } from 'boot/axios';
|
||||||
|
import { useFlowEditorStore } from 'stores/flowEditor';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'actionSelect',
|
name: 'actionSelect',
|
||||||
@@ -25,30 +51,74 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
filter:String
|
filter:String
|
||||||
},
|
},
|
||||||
setup(props) {
|
emits:[
|
||||||
|
"clearFilter"
|
||||||
|
],
|
||||||
|
setup(props,{emit}) {
|
||||||
const isLoaded=ref(false);
|
const isLoaded=ref(false);
|
||||||
const columns = [
|
const columns = [
|
||||||
{ name: 'name', required: true,label: 'アクション名',align: 'left',field: 'name',sortable: true},
|
{ name: 'name', required: true,label: 'アクション名',align: 'left',field: 'name',sortable: true},
|
||||||
{ name: 'desc', align: 'left', label: '説明', field: 'desc', sortable: true },
|
{ name: 'desc', align: 'left', label: '説明', field: 'desc', sortable: true },
|
||||||
// { name: 'content', label: '内容', field: 'content', sortable: true }
|
// { name: 'content', label: '内容', field: 'content', sortable: true }
|
||||||
];
|
];
|
||||||
const rows = reactive([])
|
const store = useFlowEditorStore();
|
||||||
|
let actionData =reactive([]);
|
||||||
|
const categorys = ref('');
|
||||||
|
const tab=ref('');
|
||||||
|
const actionForTab=computed(()=>{
|
||||||
|
const rows=[];
|
||||||
|
const actions= props.filter? actionData:actionData.filter(x=>x.categoryname===tab.value);
|
||||||
|
actions.forEach((item,index) =>{
|
||||||
|
rows.push({index,
|
||||||
|
name:item.name,
|
||||||
|
desc:item.title,
|
||||||
|
outputPoints:item.outputpoints,
|
||||||
|
property:item.property});
|
||||||
|
});
|
||||||
|
return rows;
|
||||||
|
});
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const res =await api.get('api/actions');
|
let eventId='';
|
||||||
res.data.forEach((item,index) =>
|
if(store.selectedEvent ){
|
||||||
{
|
eventId=store.selectedEvent.header!=='DELETABLE'? store.selectedEvent.eventId : store.selectedEvent.parentId;
|
||||||
rows.push({index,name:item.name,desc:item.title,outputPoints:item.outputpoints,property:item.property});
|
}
|
||||||
});
|
const res =await api.get(`api/eventactions/${store.selectedEvent.eventId}`);
|
||||||
|
actionData= res.data;
|
||||||
|
const categoryNames = Array.from(new Set(actionData.map(x=>x.categoryname)));
|
||||||
|
categorys.value=categoryNames;
|
||||||
|
tab.value = categoryNames.length>0? categoryNames[0]:'';
|
||||||
isLoaded.value=true;
|
isLoaded.value=true;
|
||||||
});
|
});
|
||||||
|
watch(props.filter,()=>{
|
||||||
|
if(props.filter && props.filter!==''){
|
||||||
|
tab.value='';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watch(tab,()=>{
|
||||||
|
if(tab.value!==''){
|
||||||
|
emit('clearFilter','');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// watchEffect(()=>{
|
||||||
|
// if(props.filter && props.filter!==''){
|
||||||
|
// tab.value='';
|
||||||
|
// }
|
||||||
|
// if(tab.value!==''){
|
||||||
|
// emit('update:filter','');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
return {
|
return {
|
||||||
columns,
|
columns,
|
||||||
rows,
|
|
||||||
selected: ref([]),
|
selected: ref([]),
|
||||||
pagination:ref({
|
pagination:ref({
|
||||||
rowsPerPage:0
|
rowsPerPage:0
|
||||||
}),
|
}),
|
||||||
isLoaded,
|
isLoaded,
|
||||||
|
tab,
|
||||||
|
actionData,
|
||||||
|
categorys,
|
||||||
|
splitterModel: ref(150),
|
||||||
|
actionForTab
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -58,5 +128,6 @@ export default {
|
|||||||
.action-table{
|
.action-table{
|
||||||
min-height: 10vh;
|
min-height: 10vh;
|
||||||
max-height: 68vh;
|
max-height: 68vh;
|
||||||
|
min-width: 550px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
import { QTree, useQuasar } from 'quasar';
|
import { QTree, useQuasar } from 'quasar';
|
||||||
import { ActionFlow, RootAction } from 'src/types/ActionTypes';
|
import { ActionFlow, RootAction } from 'src/types/ActionTypes';
|
||||||
import { useFlowEditorStore } from 'stores/flowEditor';
|
import { useFlowEditorStore } from 'stores/flowEditor';
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, ref,watchEffect } from 'vue';
|
||||||
import { IKintoneEvent, IKintoneEventGroup, IKintoneEventNode } from '../../types/KintoneEvents';
|
import { IKintoneEvent, IKintoneEventGroup, IKintoneEventNode } from '../../types/KintoneEvents';
|
||||||
import FieldSelect from '../FieldSelect.vue';
|
import FieldSelect from '../FieldSelect.vue';
|
||||||
import ShowDialog from '../ShowDialog.vue';
|
import ShowDialog from '../ShowDialog.vue';
|
||||||
@@ -75,8 +75,8 @@ export default defineComponent({
|
|||||||
// const selectedFlow = store.currentFlow;
|
// const selectedFlow = store.currentFlow;
|
||||||
|
|
||||||
// const expanded=ref();
|
// const expanded=ref();
|
||||||
const selectedEvent = ref<IKintoneEvent | null>(null);
|
const selectedEvent = ref<IKintoneEvent | undefined>(store.selectedEvent);
|
||||||
const selectedChangeEvent = ref<IKintoneEventGroup | null>(null);
|
const selectedChangeEvent = ref<IKintoneEventGroup | undefined>(undefined);
|
||||||
const isFieldChange = (node: IKintoneEventNode) => {
|
const isFieldChange = (node: IKintoneEventNode) => {
|
||||||
return node.header == 'EVENT' && node.eventId.indexOf(".change.") > -1;
|
return node.header == 'EVENT' && node.eventId.indexOf(".change.") > -1;
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,9 @@ export default defineComponent({
|
|||||||
selectedEvent.value.flowData = flow;
|
selectedEvent.value.flowData = flow;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
watchEffect(()=>{
|
||||||
|
store.setCurrentEvent(selectedEvent.value);
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
// eventTree,
|
// eventTree,
|
||||||
// expanded,
|
// expanded,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
</template>
|
</template>
|
||||||
<action-select ref="appDg" name="model" :filter="filter" type="single"></action-select>
|
<action-select ref="appDg" name="model" :filter="filter" type="single" @clearFilter="onClearFilter" ></action-select>
|
||||||
</ShowDialog>
|
</ShowDialog>
|
||||||
|
|
||||||
</q-page>
|
</q-page>
|
||||||
@@ -198,7 +198,7 @@ const onSaveFlow = async () => {
|
|||||||
if (targetFlow === undefined) {
|
if (targetFlow === undefined) {
|
||||||
$q.notify({
|
$q.notify({
|
||||||
type: 'negative',
|
type: 'negative',
|
||||||
caption: "エラー",
|
caption: 'エラー',
|
||||||
message: `編集中のフローがありません。`
|
message: `編集中のフローがありません。`
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -241,6 +241,10 @@ const fetchData = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onClearFilter=()=>{
|
||||||
|
filter.value='';
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
authStore.toggleLeftMenu();
|
authStore.toggleLeftMenu();
|
||||||
fetchData();
|
fetchData();
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ export const useFlowEditorStore = defineStore('flowEditor', {
|
|||||||
setActiveNode(node: IActionNode) {
|
setActiveNode(node: IActionNode) {
|
||||||
this.activeNode = node;
|
this.activeNode = node;
|
||||||
},
|
},
|
||||||
|
setCurrentEvent(event:IKintoneEvent | undefined){
|
||||||
|
this.selectedEvent=event;
|
||||||
|
},
|
||||||
setApp(app: AppInfo) {
|
setApp(app: AppInfo) {
|
||||||
this.appInfo = app;
|
this.appInfo = app;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user