This commit is contained in:
xue jiahao
2024-12-05 17:41:00 +08:00
parent a6576827fd
commit 4336462ff1
4 changed files with 141 additions and 43 deletions

View File

@@ -1,14 +1,16 @@
<template>
<q-card :class="['domain-card', small ? 'small' : '']">
<q-card :class="['domain-card', small ? 'small' : '', item.id == activeId ? 'default': '']">
<q-card-section :class="[small ? 'q-py-sm' : '']">
<div class="row items-center no-wrap">
<div class="row no-wrap">
<div class="col">
<div :class="[small ? 'text-subtitle2' : 'text-h6']">{{ item.name }} <q-icon v-if="isNotOwnerFunc(item.id)" name="account_circle" color="teal" class="q-mb-xs"></q-icon> </div>
<div :class="[small ? 'text-subtitle2' : 'text-h6', 'ellipsis']">{{ item.name }}</div>
<div :class="[small ? 'text-caption' : 'text-subtitle2']">{{ item.url }}</div>
</div>
<!-- <div v-if="isNotOwnerFunc(item.id)" class="col-auto">
<q-icon name="account_circle" color="teal" size="2em"></q-icon>
</div> -->
<div v-if="!isOwnerFunc(item.owner.id)" class="col-auto">
<!-- <q-badge color="secondary" text-color="white" align="middle" class="q-mb-xs" label="他人の所有" /> -->
<q-chip square color="secondary" text-color="white" icon="people" label="他人の所有" size="sm" />
</div>
</div>
</q-card-section>
<q-card-section>
@@ -17,13 +19,13 @@
<div class="text-grey-7 text-caption text-weight-medium">
アカウント
</div>
<div class="smaller-font-size">{{ item.kintoneuser }}</div>
<div class="smaller-font-size">{{ item.user }}</div>
</div>
<div v-if="isNotOwnerFunc(item.id)" class="col-auto">
<div class="col-auto">
<div class="text-grey-7 text-caption text-weight-medium">
所有者
</div>
<div class="smaller-font-size">{{ item.owner }}</div>
<div class="smaller-font-size">{{ item.owner.fullName }}</div>
</div>
</div>
</q-card-section>
@@ -34,16 +36,17 @@
<script setup lang="ts">
import { defineProps, computed } from 'vue';
import { IDomain } from 'src/types/DomainTypes';
import { IDomainOwnerDisplay } from 'src/types/DomainTypes';
import { useAuthStore } from 'stores/useAuthStore';
const props = defineProps<{
item: IDomain;
item: IDomainOwnerDisplay;
small: boolean;
activeId: number;
}>();
const authStore = useAuthStore();
const isNotOwnerFunc = computed(() => (ownerId: string) => {
const isOwnerFunc = computed(() => (ownerId: string) => {
return ownerId == authStore.userId;
});
@@ -53,6 +56,12 @@ const isNotOwnerFunc = computed(() => (ownerId: string) => {
.domain-card.small {
width: 18rem;
}
.domain-card.default {
box-shadow: 0 6px 6px -3px rgba(0, 0, 0, 0.2),
0 10px 14px 1px rgba(0, 0, 0, 0.14),
0 4px 18px 3px rgba(0, 0, 0, 0.12),
inset 0 0 0px 2px #1976D2;
}
.domain-card {
width: 22rem;
word-break: break-word;

View File

@@ -16,6 +16,11 @@
</template>
</q-input>
</template>
<template v-slot:body-cell-name="prop">
<q-td :props="prop">
<q-btn flat dense :label="prop.row.name" @click="toEditFlowPage(prop.row)" ></q-btn>
</q-td>
</template>
<template v-slot:body-cell-url="prop">
<q-td :props="prop">
<a :href="prop.row.url" target="_blank" :title="prop.row.name" >
@@ -25,11 +30,31 @@
</template>
<template v-slot:body-cell-actions="p">
<q-td :props="p">
<q-btn-group flat>
<q-btn flat color="primary" padding="xs" size="1em" icon="edit_note" @click="toEditFlowPage(p.row)" />
<q-btn disabled flat color="primary" padding="xs" size="1em" icon="history" @click="showHistory(p.row)" />
<q-btn disabled flat color="negative" padding="xs" size="1em" icon="delete_outline" @click="removeRow(p.row)" />
</q-btn-group>
<q-btn flat padding="xs" round size="1em" icon="more_vert">
<q-menu >
<q-list dense style="min-width: 100px">
<q-item clickable v-close-popup @click="toEditFlowPage(p.row)">
<q-item-section>
<q-icon size="1.2em" name="account_tree" />
</q-item-section>
<q-item-section>設定</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="showHistory(p.row)">
<q-item-section>
<q-icon size="1.2em" name="history" />
</q-item-section>
<q-item-section>履歴</q-item-section>
</q-item>
<q-separator />
<q-item class="text-red" clickable v-close-popup @click="removeRow(p.row)">
<q-item-section>
<q-icon size="1.2em" name="delete_outline" />
</q-item-section>
<q-item-section>削除</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</template>
</q-table>
@@ -78,7 +103,7 @@ const columns = [
{ name: 'user', label: '最後更新者', field: 'user', align: 'left', sortable: true},
{ name: 'updatetime', label: '最後更新日', field: 'updatetime', align: 'left', sortable: true},
{ name: 'version', label: 'バージョン', field: 'version', align: 'left', sortable: true, sort: numberStringSorting },
{ name: 'actions', label: '操作', field: 'actions' }
{ name: 'actions', label: '', field: 'actions' }
];
const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });
@@ -96,7 +121,7 @@ const getApps = async () => {
loading.value = true;
rowIds.clear();
const result = await api.get('api/apps');
rows.value = result.data.map((item: IManagedApp) => {
rows.value = result.data.data.map((item: IManagedApp) => {
rowIds.add(item.appid);
return appToAppDisplay(item)
}).sort((a: IAppDisplay, b: IAppDisplay) => a.sortId - b.sortId); // set default order

View File

@@ -17,12 +17,15 @@
</q-input>
</template>
<template v-slot:body-cell-name="p">
<q-td class="flex justify-between items-center" :props="p">
<div>
{{ p.row.name }}
<!-- <q-icon class="q-ml-xs" title="共有中です" name="people" :color="p.row.domainActive ? 'grey-8' : 'grey-4'" /> -->
</div>
<template v-slot:header-cell-active="p">
<q-th auto-width :props="p">
<q-select class="filter-header" v-model="activeFilter" :options="activeOptions" @update:model-value="activeFilterUpdate" borderless
dense options-dense hide-bottom-space/>
</q-th>
</template>
<template v-slot:body-cell-active="p">
<q-td auto-width :props="p">
<q-badge v-if="!p.row.domainActive" color="grey">未启用</q-badge>
<q-badge v-if="p.row.id == currentDomainId" color="primary">現在</q-badge>
</q-td>
@@ -30,11 +33,31 @@
<template v-slot:body-cell-actions="p">
<q-td :props="p">
<q-btn-group flat>
<q-btn flat color="primary" padding="xs" size="1em" icon="edit_note" @click="editRow(p.row)" />
<q-btn flat color="primary" padding="xs" size="1em" icon="person_add_alt" @click="openShareDg(p.row)" />
<q-btn flat color="negative" padding="xs" size="1em" icon="delete_outline" @click="removeRow(p.row)" />
</q-btn-group>
<q-btn flat padding="xs" round size="1em" icon="more_vert">
<q-menu >
<q-list dense style="min-width: 100px">
<q-item clickable v-close-popup @click="editRow(p.row)">
<q-item-section>
<q-icon size="1.2em" name="edit_note" />
</q-item-section>
<q-item-section>編集</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="openShareDg(p.row)">
<q-item-section>
<q-icon size="1.2em" name="person_add_alt" />
</q-item-section>
<q-item-section>共有</q-item-section>
</q-item>
<q-separator />
<q-item class="text-red" clickable v-close-popup @click="removeRow(p.row)">
<q-item-section>
<q-icon size="1.2em" name="delete_outline" />
</q-item-section>
<q-item-section>削除</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</template>
@@ -163,10 +186,11 @@ const columns = [
// classes: inactiveRowClass
// },
{ name: 'name', label: '環境名', field: 'name', align: 'left', sortable: true, classes: inactiveRowClass },
{ name: 'active', label: 'x', align: 'left', field: 'domainActive', classes: inactiveRowClass },
{ name: 'url', label: 'URL', field: 'url', align: 'left', sortable: true, classes: inactiveRowClass },
{ name: 'user', label: 'ログイン名', field: 'user', align: 'left', classes: inactiveRowClass },
{ name: 'owner', label: '所有者', field: row => row.owner.fullName, align: 'left', classes: inactiveRowClass },
{ name: 'actions', label: '操作', field: 'actions', classes: inactiveRowClass }
{ name: 'actions', label: '', field: 'actions', classes: inactiveRowClass }
];
const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });
@@ -180,6 +204,10 @@ const show = ref(false);
const confirm = ref(false);
const resetPsw = ref(false);
const activeOptions = ['全データ', '启用', '未启用']
const activeFilter = ref('全データ');
const currentDomainId = computed(() => authStore.currentDomain.id);
// const tenantid = ref(authStore.currentDomain.id);
const name = ref('');
@@ -194,7 +222,21 @@ let editId = ref(0);
const shareDg = ref(false);
const shareDomain = ref<IDomainOwnerDisplay>();
const getDomain = async () => {
const activeFilterUpdate = (selected) => {
switch (selected) {
case '启用':
getDomain((row) => row.domainActive)
break;
case '未启用':
getDomain((row) => !row.domainActive)
break;
default:
getDomain()
break;
}
}
const getDomain = async (filter = () => true) => {
loading.value = true;
const { data } = await api.get<{data:IDomain[]}>(`api/domains`);
rows.value = data.data.map((item) => {
@@ -217,7 +259,7 @@ const getDomain = async () => {
isSuperuser: item.owner.is_superuser,
}
}
});
}).filter(filter);
loading.value = false;
}
@@ -333,8 +375,18 @@ const onReset = () => {
}
</script>
<style lang="scss">
.filter-header .q-field__native {
font-size: 12px;
font-weight: 500;
}
.filter-header .q-icon {
width: 12px;
}
.q-table td.inactive-row {
color: #aaa;
background-color: #fafafa;
}
.q-table tr > td.inactive-row:last-child {
color: inherit;
}
</style>

View File

@@ -29,14 +29,14 @@
<template v-slot:item="props">
<div class="q-pa-sm">
<domain-card :item="props.row">
<domain-card :item="props.row" :active-id="activeDomainId">
<template v-slot:actions>
<q-card-actions align="right">
<q-chip v-if="isActive(props.row.id)" outline color="teal" text-color="white" icon="done">
<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="isNotOwner(props.row.id) || activeDomainLoadingId === props.row.id" :text-color="isNotOwner(props.row.id)?'grey':''" :loading="deleteDomainLoadingId === props.row.id" @click="clickDeleteConfirm(props.row)">削除</q-btn>
<q-btn flat :disable="isNotOwner(props.row.owner.id) || activeDomainLoadingId === props.row.id" :text-color="isNotOwner(props.row.owner.id)?'grey':''" :loading="deleteDomainLoadingId === props.row.id" @click="clickDeleteConfirm(props.row)">削除</q-btn>
</q-card-actions>
</template>
</domain-card>
@@ -70,6 +70,7 @@
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';
@@ -77,7 +78,7 @@ import DomainSelect from 'components/DomainSelect.vue';
const authStore = useAuthStore();
const pagination = ref({ sortBy: 'id', rowsPerPage: 0 });
const rows = ref([] as any[]);
const rows = ref<IDomainOwnerDisplay[]>([]);
const rowIds = new Set<string>();
const initLoading = ref(true);
const addUserDomainLoading = ref(false);
@@ -88,7 +89,7 @@ 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: 'kintoneuser', sortable: true },
{ name: 'kintoneuser', label: 'User', field: 'user', sortable: true },
];
const userDomainTableFilter = ref();
@@ -162,7 +163,7 @@ const isActive = computed(() => (id: number) => {
});
const isNotOwner = computed(() => (ownerId: string) => {
return ownerId == authStore.userId;
return ownerId !== authStore.userId;
});
const getDomain = async (userId? : string) => {
@@ -171,16 +172,27 @@ const getDomain = async (userId? : string) => {
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.reduce((acc, item) => {
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,
kintoneuser: item.kintoneuser,
ownerEmail: item.owner.email,
owner: item.owner.first_name + ' ' + item.owner.last_name,
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;