This commit is contained in:
2024-11-26 15:19:04 +09:00
8 changed files with 159 additions and 59 deletions

View File

@@ -12,10 +12,10 @@
:disable="isUnclickable" :disable="isUnclickable"
> >
<q-list> <q-list>
<q-item v-for="domain in domains" :key="domain.domainName" <q-item :active="isCurrentDomain(domain)" active-class="active-domain-item" v-for="domain in domains" :key="domain.domainName"
clickable v-close-popup @click="onItemClick(domain)"> clickable v-close-popup @click="onItemClick(domain)">
<q-item-section side> <q-item-section side>
<q-icon name="share" size="sm" color="orange" text-color="white"></q-icon> <q-icon name="share" size="sm" :color="isCurrentDomain(domain) ? 'orange': ''" text-color="white"></q-icon>
</q-item-section> </q-item-section>
<q-item-section> <q-item-section>
<q-item-label>{{domain.domainName}}</q-item-label> <q-item-label>{{domain.domainName}}</q-item-label>
@@ -27,21 +27,28 @@
</template> </template>
<script setup lang="ts" > <script setup lang="ts" >
import { IDomainInfo } from 'src/types/ActionTypes'; import { IDomainInfo } from 'src/types/DomainTypes';
import { useAuthStore,IUserState } from 'stores/useAuthStore'; import { useAuthStore } from 'stores/useAuthStore';
import { ref, computed } from 'vue'; import { useDomainStore } from 'src/stores/useDomainStore';
import { computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
const userStore = useAuthStore(); const userStore = useAuthStore();
const domainStore = useDomainStore();
const route = useRoute() const route = useRoute()
const domains = ref<IDomainInfo[]>([]); const domains = computed(() => domainStore.userDomains);
(async ()=>{ (async ()=>{
domains.value = await userStore.getUserDomains(); await domainStore.loadUserDomains();
})(); })();
const isUnclickable = computed(()=>{ const isUnclickable = computed(()=>{
return route.path.startsWith('/FlowChart/') || domains.value === undefined || domains.value.length === 0; return route.path.startsWith('/FlowChart/') || domains.value === undefined || domains.value.length === 0;
}); });
const isCurrentDomain=(domain:IDomainInfo)=>{
return domain.id === userStore.currentDomain.id;
}
const onItemClick=(domain:IDomainInfo)=>{ const onItemClick=(domain:IDomainInfo)=>{
console.log(domain); console.log(domain);
@@ -54,6 +61,11 @@ const onItemClick=(domain:IDomainInfo)=>{
cursor: default !important; cursor: default !important;
} }
.q-item.active-domain-item {
color: inherit;
background: #eee;
}
.q-btn.disabled.customized-disabled-btn * { .q-btn.disabled.customized-disabled-btn * {
cursor: default !important; cursor: default !important;
} }

View File

@@ -17,6 +17,14 @@
</q-input> </q-input>
</template> </template>
<template v-slot:body-cell-name="p">
<q-td class="flex justify-between items-center" :props="p">
{{ p.row.name }}
<q-badge v-if="!p.row.domainActive" color="grey">未启用</q-badge>
<q-badge v-if="p.row.id == currendDomainId" color="primary">現在</q-badge>
</q-td>
</template>
<template v-slot:body-cell-actions="p"> <template v-slot:body-cell-actions="p">
<q-td :props="p"> <q-td :props="p">
<q-btn-group flat> <q-btn-group flat>
@@ -45,7 +53,7 @@
<q-input filled v-model="name" label="環境名 *" hint="kintoneの環境名を入力してください" lazy-rules <q-input filled v-model="name" label="環境名 *" hint="kintoneの環境名を入力してください" lazy-rules
:rules="[val => val && val.length > 0 || 'kintoneの環境名を入力してください。']" /> :rules="[val => val && val.length > 0 || 'kintoneの環境名を入力してください。']" />
<q-input filled type="url" v-model="url" label="Kintone url" hint="KintoneのURLを入力してください" lazy-rules <q-input filled type="url" v-model.trim="url" label="Kintone url" hint="KintoneのURLを入力してください" lazy-rules
:rules="[val => val && val.length > 0, isDomain || 'KintoneのURLを入力してください']" /> :rules="[val => val && val.length > 0, isDomain || 'KintoneのURLを入力してください']" />
<q-input filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" lazy-rules <q-input filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" lazy-rules
@@ -60,6 +68,15 @@
</template> </template>
</q-input> </q-input>
<q-item tag="label" class="q-pl-sm q-pr-none q-py-xs">
<q-item-section>
<q-item-label>ドメインの有効化</q-item-label>
</q-item-section>
<q-item-section avatar>
<q-toggle v-model="domainActive" />
</q-item-section>
</q-item>
<div class="q-gutter-y-md" v-if="!isCreate"> <div class="q-gutter-y-md" v-if="!isCreate">
<q-separator /> <q-separator />
@@ -112,14 +129,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'; import { ref, onMounted, computed } from 'vue';
import { api } from 'boot/axios'; import { api } from 'boot/axios';
import { useAuthStore } from 'stores/useAuthStore'; import { useAuthStore } from 'stores/useAuthStore';
import { useDomainStore } from 'stores/useDomainStore';
import { IDomain, IDomainDisplay, IDomainSubmit } from '../types/DomainTypes';
const authStore = useAuthStore(); const authStore = useAuthStore();
const domainStore = useDomainStore();
const inactiveRowClass = (row: IDomainDisplay) => row.domainActive ? '' : 'inactive-row';
const columns = [ const columns = [
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true }, { name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true, classes: inactiveRowClass },
{ {
name: 'tenantid', name: 'tenantid',
required: true, required: true,
@@ -127,22 +148,24 @@ const columns = [
field: row => row.tenantid, field: row => row.tenantid,
format: val => `${val}`, format: val => `${val}`,
align: 'left', align: 'left',
sortable: true sortable: true,
classes: inactiveRowClass
}, },
{ name: 'name', label: '環境名', field: 'name', align: 'left', sortable: true }, { name: 'name', label: '環境名', field: 'name', align: 'left', sortable: true, classes: inactiveRowClass },
{ name: 'url', label: 'URL', field: 'url', align: 'left', sortable: true }, { name: 'url', label: 'URL', field: 'url', align: 'left', sortable: true, classes: inactiveRowClass },
{ name: 'user', label: 'ログイン名', field: 'user', align: 'left', }, { name: 'user', label: 'ログイン名', field: 'user', align: 'left', classes: inactiveRowClass },
{ name: 'actions', label: '操作', field: 'actions' } { name: 'actions', label: '操作', field: 'actions' }
]; ];
const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 }); const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });
const loading = ref(false); const loading = ref(false);
const filter = ref(''); const filter = ref('');
const rows = ref([]); const rows = ref<IDomainDisplay[]>([]);
const show = ref(false); const show = ref(false);
const confirm = ref(false); const confirm = ref(false);
const resetPsw = ref(false); const resetPsw = ref(false);
const currendDomainId = computed(() => authStore.currentDomain.id);
const tenantid = ref(authStore.currentDomain.id); const tenantid = ref(authStore.currentDomain.id);
const name = ref(''); const name = ref('');
const url = ref(''); const url = ref('');
@@ -150,15 +173,25 @@ const isPwd = ref(true);
const kintoneuser = ref(''); const kintoneuser = ref('');
const kintonepwd = ref(''); const kintonepwd = ref('');
const kintonepwdBK = ref(''); const kintonepwdBK = ref('');
const domainActive = ref(true);
const isCreate = ref(true); const isCreate = ref(true);
let editId = ref(0); let editId = ref(0);
let ownerid = ref('');
const getDomain = async () => { const getDomain = async () => {
loading.value = true; loading.value = true;
const userId = authStore.userId; const userId = authStore.userId;
const result = await api.get(`api/domain?userId=${userId}`); const result = await api.get<IDomain[]>(`api/domain?userId=${userId}`);
rows.value = result.data.map((item) => { rows.value = result.data.map((item) => {
return { id: item.id, tenantid: item.tenantid, name: item.name, url: item.url, user: item.kintoneuser, password: item.kintonepwd } return {
id: item.id,
tenantid: item.tenantid,
domainActive: item.is_active,
name: item.name,
url: item.url,
user: item.kintoneuser,
password: item.kintonepwd,
}
}); });
loading.value = false; loading.value = false;
} }
@@ -174,7 +207,7 @@ const addRow = () => {
show.value = true; show.value = true;
} }
const removeRow = (row) => { const removeRow = (row: IDomainDisplay) => {
confirm.value = true; confirm.value = true;
editId.value = row.id; editId.value = row.id;
} }
@@ -195,6 +228,7 @@ const editRow = (row) => {
url.value = row.url; url.value = row.url;
kintoneuser.value = row.user; kintoneuser.value = row.user;
kintonepwd.value = row.password; kintonepwd.value = row.password;
domainActive.value = row.domainActive;
isPwd.value = true; isPwd.value = true;
show.value = true; show.value = true;
}; };
@@ -214,36 +248,24 @@ const closeDg = () => {
} }
const onSubmit = () => { const onSubmit = () => {
if (editId.value !== 0) { const method = editId.value !== 0 ? 'put' : 'post';
api.put(`api/domain`, { const param: IDomainSubmit = {
'id': editId.value, 'id': editId.value,
'tenantid': tenantid.value, 'tenantid': tenantid.value,
'name': name.value, 'name': name.value,
'url': url.value, 'url': url.value,
'kintoneuser': kintoneuser.value, 'kintoneuser': kintoneuser.value,
'kintonepwd': isCreate.value || resetPsw.value ? kintonepwd.value : '' 'kintonepwd': ((isCreate.value && editId.value == 0) || resetPsw.value) ? kintonepwd.value : '',
}).then(() => { 'is_active': domainActive.value,
'ownerid': authStore.userId || ''
}
api[method].apply(api, [`api/domain`, param]).then(() => {
getDomain(); getDomain();
domainStore.loadUserDomains();
closeDg(); closeDg();
onReset(); onReset();
}) })
} }
else {
api.post(`api/domain`, {
'id': 0,
'tenantid': tenantid.value,
'name': name.value,
'url': url.value,
'kintoneuser': kintoneuser.value,
'kintonepwd': kintonepwd.value
}).then(() => {
getDomain();
closeDg();
onReset();
})
}
}
const onReset = () => { const onReset = () => {
name.value = ''; name.value = '';
@@ -252,7 +274,14 @@ const onReset = () => {
kintonepwd.value = ''; kintonepwd.value = '';
isPwd.value = true; isPwd.value = true;
editId.value = 0; editId.value = 0;
ownerid.value = '';
isCreate.value = true; isCreate.value = true;
domainActive.value = true;
resetPsw.value = false resetPsw.value = false
} }
</script> </script>
<style lang="scss">
.q-table td.inactive-row {
color: #aaa;
}
</style>

View File

@@ -1,7 +1,7 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { api } from 'boot/axios'; import { api } from 'boot/axios';
import { router } from 'src/router'; import { router } from 'src/router';
import { IDomainInfo } from '../types/ActionTypes'; import { IDomainInfo } from '../types/DomainTypes';
import { jwtDecode } from 'jwt-decode'; import { jwtDecode } from 'jwt-decode';
interface UserInfo { interface UserInfo {
firstName: string; firstName: string;
@@ -76,7 +76,9 @@ export const useAuthStore = defineStore('auth', {
async getUserDomains(): Promise<IDomainInfo[]> { async getUserDomains(): Promise<IDomainInfo[]> {
const resp = await api.get(`api/domain`); const resp = await api.get(`api/domain`);
const domains = resp.data as any[]; const domains = resp.data as any[];
return domains.map((data) => ({ return domains
.filter(data => data.is_active)
.map((data) => ({
id: data.id, id: data.id,
domainName: data.name, domainName: data.name,
kintoneUrl: data.url, kintoneUrl: data.url,

View File

@@ -0,0 +1,23 @@
import { defineStore } from 'pinia';
import { api } from 'boot/axios';
import { IDomainInfo, IDomain } from '../types/DomainTypes';
export const useDomainStore = defineStore('domain', {
state: () => ({
userDomains: [] as IDomainInfo[],
}),
actions: {
async loadUserDomains(): Promise<IDomainInfo[]> {
const resp = await api.get(`api/domain`);
const domains = resp.data as IDomain[];
this.userDomains = domains
.filter(data => data.is_active)
.map((data) => ({
id: data.id,
domainName: data.name,
kintoneUrl: data.url,
}));
return this.userDomains;
},
},
});

View File

@@ -1,9 +1,4 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
export interface IDomainInfo{
id:number;
domainName:string;
kintoneUrl:string;
}
/** /**
* アプリ情報 * アプリ情報

View File

@@ -1,8 +1,4 @@
interface IUser { import { IUser } from './UserTypes';
first_name: string;
last_name: string;
email: string;
}
export interface IManagedApp { export interface IManagedApp {
appid: string; appid: string;

View File

@@ -0,0 +1,35 @@
import { IDomain } from './ActionTypes';
import { IUser } from './UserTypes';
export interface IDomainInfo {
id: number;
domainName: string;
kintoneUrl: string;
}
export interface IDomain {
id: number;
tenantid: string;
name: string;
url: string;
kintoneuser: string,
kintonepwd: string,
create_time: string;
update_time: string;
is_active: boolean;
owner: IUser
}
export interface IDomainSubmit extends Omit<IDomain, 'create_time' | 'update_time' | 'owner'> {
ownerid: string;
}
export interface IDomainDisplay {
id: number;
tenantid: string;
name: string;
url: string;
user: string;
password: string;
domainActive: boolean;
}

View File

@@ -0,0 +1,8 @@
export interface IUser {
first_name: string;
last_name: string;
email: string;
is_active: boolean,
is_superuser: boolean,
roles: string[]
}