diff --git a/frontend/src/components/DomainSelector.vue b/frontend/src/components/DomainSelector.vue
index c0ea828..e2cb112 100644
--- a/frontend/src/components/DomainSelector.vue
+++ b/frontend/src/components/DomainSelector.vue
@@ -22,7 +22,9 @@ const userStore = useAuthStore();
.q-btn.disabled.customized-disabled-btn {
opacity: 1 !important;
cursor: default !important;
-
+ .q-icon.q-btn-dropdown__arrow {
+ display: none;
+ }
* {
cursor: default !important;
}
diff --git a/frontend/src/components/ShareDomain/RoleLabel.vue b/frontend/src/components/ShareDomain/RoleLabel.vue
index 7f694de..8e84303 100644
--- a/frontend/src/components/ShareDomain/RoleLabel.vue
+++ b/frontend/src/components/ShareDomain/RoleLabel.vue
@@ -1,11 +1,15 @@
- 所有者
- 管理者
+ 所有者
+
+ 自分
diff --git a/frontend/src/components/ShareDomain/ShareDomainDialog.vue b/frontend/src/components/ShareDomain/ShareDomainDialog.vue
index 0cd5f55..54d4327 100644
--- a/frontend/src/components/ShareDomain/ShareDomainDialog.vue
+++ b/frontend/src/components/ShareDomain/ShareDomainDialog.vue
@@ -37,7 +37,7 @@
{{scope.opt.fullName}}
{{scope.opt.email}}
-
+
@@ -47,7 +47,7 @@
-
+
@@ -72,15 +72,19 @@ import { ref, watch, onMounted } from 'vue';
import { IDomainOwnerDisplay } from '../../types/DomainTypes';
import { IUser, IUserDisplay } from '../../types/UserTypes';
import { api } from 'boot/axios';
+import { useAuthStore } from 'stores/useAuthStore';
import SharingUserList from 'components/ShareDomain/SharingUserList.vue';
import RoleLabel from 'components/ShareDomain/RoleLabel.vue';
import { Dialog } from 'quasar'
+const authStore = useAuthStore();
+
interface Props {
modelValue: boolean;
domain: IDomainOwnerDisplay;
dialogTitle: string;
userListTitle: string;
+ hideSelf: boolean;
shareApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise;
removeSharedApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise;
getSharedApi: (domain: IDomainOwnerDisplay) => Promise;
@@ -186,28 +190,43 @@ const removeShareTo = async (user: IUserDisplayWithShareRole) => {
loading.value = true;
user.isRemoving = true;
await props.removeSharedApi(user, props.domain);
+ if (isCurrentDomain()) {
+ await authStore.loadCurrentDomain();
+ }
await loadShared();
loading.value = false;
};
+const isCurrentDomain = () => {
+ return props.domain.id === authStore.currentDomain.id;
+}
+
const loadShared = async () => {
loading.value = true;
sharedUsersIdSet.clear();
+ if(props.hideSelf) {
+ sharedUsersIdSet.add((Number)(authStore.userId));
+ }
+
const { data } = await props.getSharedApi(props.domain);
- sharedUsers.value = data.data.map((item: IUser) => {
+
+ sharedUsers.value = data.data.reduce((arr: IUserDisplayWithShareRole[], item: IUser) => {
const val = itemToDisplay(item);
- sharedUsersIdSet.add(val.id);
- // for sort
- if (isOwner(item.id)) {
- val.role = 2;
- } else if (isManager(item.id)) {
- val.role = 1;
- } else {
- val.role = 0;
+ if(!sharedUsersIdSet.has(val.id)) {
+ sharedUsersIdSet.add(val.id);
+ // for sort
+ if (isOwner(val.id)) {
+ val.role = 2;
+ } else if (isManager(val.id)) {
+ val.role = 1;
+ } else {
+ val.role = 0;
+ }
+ arr.push(val);
}
- return val;
- }).reverse().sort((a: IUserDisplayWithShareRole, b: IUserDisplayWithShareRole) => b.role - a.role);
+ return arr;
+ }, []).sort((a: IUserDisplayWithShareRole, b: IUserDisplayWithShareRole) => b.role - a.role);
canSharedUsers.value = allUsers.value.filter((item) => !sharedUsersIdSet.has(item.id));
canSharedUserFilteredOptions.value = canSharedUsers.value;
diff --git a/frontend/src/components/ShareDomain/ShareManageDialog.vue b/frontend/src/components/ShareDomain/ShareManageDialog.vue
index 8455ec7..b2a7045 100644
--- a/frontend/src/components/ShareDomain/ShareManageDialog.vue
+++ b/frontend/src/components/ShareDomain/ShareManageDialog.vue
@@ -7,6 +7,7 @@
:remove-shared-api="removeSharedApi"
:get-shared-api="getSharedApi"
:model-value="modelValue"
+ hide-self
@update:modelValue="updateModelValue"
@close="close"
/>
diff --git a/frontend/src/components/TableActionMenu.vue b/frontend/src/components/TableActionMenu.vue
index 9e40f53..5d7a6ce 100644
--- a/frontend/src/components/TableActionMenu.vue
+++ b/frontend/src/components/TableActionMenu.vue
@@ -3,11 +3,15 @@
-
+
{{ item.label }}
+
+ {{ isFunction(item.tooltip) ? item.tooltip(row) : item.tooltip }}
+
@@ -23,6 +27,8 @@ import { IDomainOwnerDisplay } from '../types/DomainTypes';
interface Action {
label: string;
icon?: string;
+ tooltip?: string|((row: IDomainOwnerDisplay) => string);
+ disable?: boolean|((row: IDomainOwnerDisplay) => boolean);
action: (row: any) => void|Promise;
class?: string;
}
@@ -54,6 +60,10 @@ export default {
methods: {
isAction(item: MenuItem): item is Action {
return !('separator' in item);
+ },
+
+ isFunction(item: any): item is ((row: IDomainOwnerDisplay) => boolean|string) {
+ return typeof item === 'function';
}
}
};
diff --git a/frontend/src/components/UserInfoButton.vue b/frontend/src/components/UserInfoButton.vue
new file mode 100644
index 0000000..ac98544
--- /dev/null
+++ b/frontend/src/components/UserInfoButton.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
{{ userInfo.fullName }}
+
{{ userInfo.email }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/layouts/MainLayout.vue b/frontend/src/layouts/MainLayout.vue
index 9ad772c..925bcd7 100644
--- a/frontend/src/layouts/MainLayout.vue
+++ b/frontend/src/layouts/MainLayout.vue
@@ -8,7 +8,7 @@
V{{ version }}
-
+
@@ -37,6 +37,7 @@
import { computed, onMounted, reactive } from 'vue';
import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue';
import DomainSelector from 'components/DomainSelector.vue';
+import UserInfoButton from 'components/UserInfoButton.vue';
import { useAuthStore } from 'stores/useAuthStore';
import { useRoute } from 'vue-router';
diff --git a/frontend/src/pages/AppVersionManagement.vue b/frontend/src/pages/AppVersionManagement.vue
index f053ad9..04faafe 100644
--- a/frontend/src/pages/AppVersionManagement.vue
+++ b/frontend/src/pages/AppVersionManagement.vue
@@ -47,8 +47,7 @@
-
-
+
@@ -119,7 +118,7 @@ const confirmDialog = ref(false);
const deleteUserLoading = ref(false);
const actionList = ref([
- { label: 'プル', icon: 'flag', action: changeVersion },
+ { label: '回復する', icon: 'flag', action: changeVersion },
// { label: 'プレビュー', icon: 'visibility', action: toVersionHistoryPage },
// { separator: true },
// { label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
diff --git a/frontend/src/pages/TenantDomain.vue b/frontend/src/pages/TenantDomain.vue
index 80a235e..04d2be8 100644
--- a/frontend/src/pages/TenantDomain.vue
+++ b/frontend/src/pages/TenantDomain.vue
@@ -31,6 +31,13 @@
+
+
+ 自分
+ {{ p.row.owner.fullName }}
+
+
+
@@ -115,7 +122,7 @@
- ドメイン利用/管理権限を確認中
+ ドメイン利用権限を確認中
@@ -131,7 +138,7 @@
-
+
@@ -171,7 +178,7 @@ const columns = [
{ name: 'active', label: '', 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: IDomainOwnerDisplay) => row.owner.fullName, align: 'left', classes: inactiveRowClass },
+ { name: 'owner', label: '所有者', field: '', align: 'left', classes: inactiveRowClass },
{ name: 'actions', label: '', field: 'actions', classes: inactiveRowClass }
];
@@ -228,11 +235,17 @@ const SHARE_MANAGE = 'manage';
const actionList = [
{ label: '編集', icon: 'edit_note', action: editRow },
{ label: '利用権限設定', icon: 'person_add_alt', action: (row: IDomainOwnerDisplay) => {openShareDg(SHARE_USE, row)} },
- { label: '管理権限設定', icon: 'add_moderator', action: (row: IDomainOwnerDisplay) => {openShareDg(SHARE_MANAGE, row)} },
+ { label: '管理権限設定', icon: 'add_moderator',
+ disable: (row: IDomainOwnerDisplay) => !isOwner(row),
+ tooltip: (row: IDomainOwnerDisplay) => isOwner(row) ? '' : 'ドメイン所有者でないため、操作できません',
+ action: (row: IDomainOwnerDisplay) => {openShareDg(SHARE_MANAGE, row)}
+ },
{ separator: true },
{ label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
];
+const isOwner = (row: IDomainOwnerDisplay) => row.owner.id === Number(authStore.userId);
+
const getDomain = async (filter?: (row: IDomainOwnerDisplay) => boolean) => {
loading.value = true;
const { data } = await api.get<{data:IDomain[]}>(`api/domains`);
diff --git a/frontend/src/pages/UserDomain.vue b/frontend/src/pages/UserDomain.vue
index 1a41880..481a3d2 100644
--- a/frontend/src/pages/UserDomain.vue
+++ b/frontend/src/pages/UserDomain.vue
@@ -36,7 +36,9 @@
既定
既定にする
- 削除
+
+ 削除
+
@@ -165,10 +167,6 @@ const isActive = computed(() => (id: number) => {
return id == activeDomainId.value;
});
-const isNotOwner = computed(() => (ownerId: string) => {
- return ownerId !== authStore.userId;
-});
-
const getDomain = async (userId? : string) => {
rowIds.clear();
const resp = await api.get(`api/defaultdomain`);
diff --git a/frontend/src/stores/useAuthStore.ts b/frontend/src/stores/useAuthStore.ts
index 6187b7d..f45296c 100644
--- a/frontend/src/stores/useAuthStore.ts
+++ b/frontend/src/stores/useAuthStore.ts
@@ -8,6 +8,7 @@ import { useAppStore } from './useAppStore';
interface UserInfo {
firstName: string;
lastName: string;
+ fullName: string;
email: string;
}
@@ -60,7 +61,7 @@ export const useAuthStore = defineStore('auth', {
this.userId = tokenJson.sub;
this.permissions = (tokenJson as any).permissions==='ALL' ? 'admin': 'user';
api.defaults.headers['Authorization'] = 'Bearer ' + this.token;
- this.currentDomain = await this.getCurrentDomain();
+ await this.loadCurrentDomain();
this.userInfo = await this.getUserInfo();
router.push(this.returnUrl || '/');
return true;
@@ -69,10 +70,10 @@ export const useAuthStore = defineStore('auth', {
return false;
}
},
- async getCurrentDomain(): Promise {
+ async loadCurrentDomain() {
const resp = await api.get(`api/defaultdomain`);
const activedomain = resp?.data?.data;
- return {
+ this.currentDomain = {
id: activedomain?.id,
domainName: activedomain?.name,
kintoneUrl: activedomain?.url,
@@ -83,6 +84,7 @@ export const useAuthStore = defineStore('auth', {
return {
firstName: resp.first_name,
lastName: resp.last_name,
+ fullName: resp.last_name + ' ' + resp.first_name,
email: resp.email,
}
},