Files
KintoneAppBuilder/frontend/src/pages/UserDomain.vue
2025-03-18 11:45:22 +08:00

220 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="q-pa-md">
<div class="q-gutter-sm row items-start">
<q-breadcrumbs>
<q-breadcrumbs-el icon="assignment_ind" label="接続先の割り当て" />
</q-breadcrumbs>
</div>
<q-table :loading="initLoading" grid grid-header title="Domain" selection="single" :rows="rows" :columns="columns" row-key="name"
:filter="userDomainTableFilter" virtual-scroll v-model:pagination="pagination">
<template v-slot:top>
<q-btn class="q-mx-none" color="primary" label="追加" @click="clickAddDomain()" />
<q-space />
<div class="row q-gutter-md">
<q-input borderless dense filled debounce="300" v-model="userDomainTableFilter" placeholder="検索">
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</div>
</template>
<template v-slot:header>
<div style="height: 1dvh">
</div>
</template>
<template v-slot:item="props">
<div class="q-pa-sm">
<domain-card :item="props.row" :active-id="activeDomainId">
<template v-slot:actions>
<q-card-actions align="right">
<q-chip class="no-border" v-if="isActive(props.row.id)" outline color="primary" text-color="white" icon="done">
既定
</q-chip>
<q-btn flat v-else :loading="activeDomainLoadingId === props.row.id" :disable="deleteDomainLoadingId === props.row.id" @click="activeDomain(props.row)">既定にする</q-btn>
<q-btn flat :disable="activeDomainLoadingId === props.row.id" :loading="deleteDomainLoadingId === props.row.id" @click="clickDeleteConfirm(props.row)">
削除
</q-btn>
</q-card-actions>
</template>
</domain-card>
</div>
</template>
</q-table>
<show-dialog v-model:visible="showAddDomainDg" name="ドメイン" @close="addUserDomainFinished" :ok-btn-loading="addUserDomainLoading" :ok-btn-auto-close="false">
<domain-select ref="addDomainRef" name="ドメイン" type="single" :filterInitRowsFunc="filterAddDgInitRows"></domain-select>
</show-dialog>
<q-dialog v-model="showDeleteConfirm" persistent>
<q-card>
<q-card-section class="row items-center">
<div class="q-ma-sm q-mt-md">
<q-icon name="warning" color="warning" size="2em" />
<span class="q-ml-sm">削除してもよろしいですか</span>
</div>
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="Cancel" color="primary" v-close-popup />
<q-btn flat label="OK" color="primary" v-close-popup @click="deleteDomainFinished()" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { api } from 'boot/axios';
import { useAuthStore } from 'stores/useAuthStore';
import { IDomainOwnerDisplay } from '../types/DomainTypes';
import ShowDialog from 'components/ShowDialog.vue';
import DomainCard from 'components/UserDomain/DomainCard.vue';
import DomainSelect from 'components/DomainSelect.vue';
const authStore = useAuthStore();
const pagination = ref({ sortBy: 'id', rowsPerPage: 0 });
const rows = ref<IDomainOwnerDisplay[]>([]);
const rowIds = new Set<string>();
const initLoading = ref(true);
const addUserDomainLoading = ref(false);
const activeDomainLoadingId = ref<number|undefined>(undefined);
const deleteDomainLoadingId = ref<number|undefined>(undefined);
const columns = [
{ name: 'id' },
{ name: 'name', required: true, label: 'Name', align: 'left', field: 'name', sortable: true },
{ name: 'url', align: 'center', label: 'Domain', field: 'url', sortable: true },
{ name: 'kintoneuser', label: 'User', field: 'user', sortable: true },
];
const userDomainTableFilter = ref();
let editId = ref(0);
const showAddDomainDg = ref(false);
const addDomainRef = ref();
const filterAddDgInitRows = (row: {domainActive: boolean, id: string}) => {
return row.domainActive && !rowIds.has(row.id);
}
const clickAddDomain = () => {
editId.value = 0;
showAddDomainDg.value = true;
};
const addUserDomainFinished = async (val: string) => {
showAddDomainDg.value = true;
const selected = addDomainRef.value.selected;
if (val == 'OK' && selected.length > 0) {
addUserDomainLoading.value = true;
const { data } = await api.post('api/userdomain', {
userid: authStore.userId,
domainid: selected[0].id,
});
if (rows.value.length === 0 && data.data) {
const domain = data.data;
await authStore.setCurrentDomain({
id: domain.id,
kintoneUrl: domain.url,
domainName: domain.name
});
}
await getDomain();
}
addUserDomainLoading.value = false;
showAddDomainDg.value = false;
};
const showDeleteConfirm = ref(false);
const clickDeleteConfirm = (row: any) => {
showDeleteConfirm.value = true;
editId.value = row.id;
};
const deleteDomainFinished = async () => {
deleteDomainLoadingId.value = editId.value;
const { data } = await api.delete(`api/domain/${editId.value}/${authStore.userId}`)
if (data.msg == 'OK' && authStore.currentDomain.id === editId.value) {
authStore.setCurrentDomain();
}
editId.value = 0;
await getDomain();
deleteDomainLoadingId.value = undefined;
};
const activeDomain = async (domain: any) => {
activeDomainLoadingId.value = domain.id;
await authStore.setCurrentDomain({
id: domain.id,
kintoneUrl: domain.url,
domainName: domain.name
});
await getDomain();
activeDomainLoadingId.value = undefined;
};
let activeDomainId = ref(0);
const isActive = computed(() => (id: number) => {
return id == activeDomainId.value;
});
const getDomain = async (userId? : string) => {
rowIds.clear();
const resp = await api.get('api/defaultdomain');
activeDomainId.value = resp?.data?.data?.id;
const domainResult = userId ? await api.get(`api/domain?userId=${userId}`) : await api.get('api/domain');
const domains = domainResult.data as any[];
rows.value = domains.sort((a, b) => a.id - b.id).reduce((acc, item) => {
rowIds.add(item.id);
if (item.is_active) {
acc.push({
id: item.id,
tenantid: item.tenantid,
domainActive: item.is_active,
name: item.name,
url: item.url,
user: item.kintoneuser,
password: item.kintonepwd,
owner: {
id: item.owner.id,
firstName: item.owner.first_name,
lastName: item.owner.last_name,
fullNameSearch: (item.owner.last_name + item.owner.first_name).toLowerCase(),
fullName: item.owner.last_name + ' ' + item.owner.first_name,
email: item.owner.email,
isActive: item.owner.is_active,
isSuperuser: item.owner.is_superuser,
}
})
}
return acc;
}, []);
}
onMounted(async () => {
initLoading.value = true;
await getDomain();
initLoading.value = false;
})
</script>
<style lang="scss" scoped>
.domain-card {
width: 22rem;
word-break: break-word;
.smaller-font-size {
font-size: 13px;
}
}
</style>