Merge branch 'dev3' of https://dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into dev3
This commit is contained in:
19
frontend/src/components/ShareDomain/RoleLabel.vue
Normal file
19
frontend/src/components/ShareDomain/RoleLabel.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<q-badge v-if="isOwner" color="purple">所有者</q-badge>
|
||||||
|
<q-badge v-else-if="isManager" color="primary">管理者</q-badge>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { IDomainOwnerDisplay } from '../../types/DomainTypes';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
user: { id: number };
|
||||||
|
domain: IDomainOwnerDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
const isOwner = computed(() => props.user.id === props.domain.owner.id);
|
||||||
|
const isManager = computed(() => props.user.id === props.domain.owner.id); // TODO
|
||||||
|
</script>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<q-dialog :auto-close="false" :model-value="visible" persistent bordered>
|
<q-dialog :auto-close="false" :model-value="visible" persistent bordered>
|
||||||
<q-card class="dialog-content" >
|
<q-card class="dialog-content" >
|
||||||
<q-toolbar class="bg-grey-4">
|
<q-toolbar class="bg-grey-4">
|
||||||
<q-toolbar-title>「{{domain.name}}」のドメイン利用権限設定</q-toolbar-title>
|
<q-toolbar-title>{{ dialogTitle }}</q-toolbar-title>
|
||||||
<q-btn flat round dense icon="close" @click="close" />
|
<q-btn flat round dense icon="close" @click="close" />
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
|
|
||||||
@@ -18,11 +18,17 @@
|
|||||||
:options="canSharedUserFilteredOptions"
|
:options="canSharedUserFilteredOptions"
|
||||||
clearable
|
clearable
|
||||||
:placeholder="canSharedUserFilter ? '' : domain.domainActive ? '権限を付与するユーザーを選択' : 'ドメインが無効なため、権限を付与できません'"
|
:placeholder="canSharedUserFilter ? '' : domain.domainActive ? '権限を付与するユーザーを選択' : 'ドメインが無効なため、権限を付与できません'"
|
||||||
@filter="filterFn"
|
@filter="filterFn">
|
||||||
:display-value="canSharedUserFilter?`${canSharedUserFilter.fullName} (${canSharedUserFilter.email})`:''">
|
|
||||||
|
<template v-slot:selected-item="scope">
|
||||||
|
<span v-if="canSharedUserFilter">
|
||||||
|
{{ canSharedUserFilter.fullName }} ({{ canSharedUserFilter.email }})
|
||||||
|
<role-label :domain="domain" :user="scope.opt"></role-label>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<q-btn :disable="!canSharedUserFilter" :loading="addLoading" label="付与" color="primary" @click="shareTo(canSharedUserFilter as IUserDisplay)" />
|
<q-btn :disable="!canSharedUserFilter" :loading="addLoading" label="付与" color="primary" @click="shareTo(canSharedUserFilter as IUserDisplayWithShareRole)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:option="scope">
|
<template v-slot:option="scope">
|
||||||
@@ -30,14 +36,27 @@
|
|||||||
<q-item-section avatar>{{scope.opt.id}}</q-item-section>
|
<q-item-section avatar>{{scope.opt.id}}</q-item-section>
|
||||||
<q-item-section>{{scope.opt.fullName}}</q-item-section>
|
<q-item-section>{{scope.opt.fullName}}</q-item-section>
|
||||||
<q-item-section>{{scope.opt.email}}</q-item-section>
|
<q-item-section>{{scope.opt.email}}</q-item-section>
|
||||||
|
<q-item-section side>
|
||||||
|
<div style="width: 4em;">
|
||||||
|
<role-label :domain="domain" :user="scope.opt"></role-label>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</template>
|
</template>
|
||||||
</q-select>
|
</q-select>
|
||||||
<sharing-user-list class="q-mt-md" style="height: 330px" :users="sharedUsers" :loading="loading" title="ドメイン利用権限を持つユーザー">
|
|
||||||
|
<sharing-user-list class="q-mt-md" style="height: 330px" :users="sharedUsers" :loading="loading" :title="userListTitle">
|
||||||
|
<template v-slot:body-cell-role="{ row }">
|
||||||
|
<q-td>
|
||||||
|
<role-label :domain="domain" :user="row"></role-label>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:actions="{ row }">
|
<template v-slot:actions="{ row }">
|
||||||
<q-btn title="解除" flat color="primary" padding="xs" size="1em" :loading="row.id == removingUser?.id" icon="person_off" @click="removeShareTo(row)" />
|
<q-btn round title="解除" flat color="primary" padding="xs" size="1em" :loading="row.isRemoving" icon="person_off" @click="removeShareTo(row)" />
|
||||||
</template>
|
</template>
|
||||||
</sharing-user-list>
|
</sharing-user-list>
|
||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-actions align="right" class="text-primary">
|
<q-card-actions align="right" class="text-primary">
|
||||||
@@ -54,11 +73,22 @@ import { IDomainOwnerDisplay } from '../../types/DomainTypes';
|
|||||||
import { IUser, IUserDisplay } from '../../types/UserTypes';
|
import { IUser, IUserDisplay } from '../../types/UserTypes';
|
||||||
import { api } from 'boot/axios';
|
import { api } from 'boot/axios';
|
||||||
import SharingUserList from 'components/ShareDomain/SharingUserList.vue';
|
import SharingUserList from 'components/ShareDomain/SharingUserList.vue';
|
||||||
|
import RoleLabel from 'components/ShareDomain/RoleLabel.vue';
|
||||||
import { Dialog } from 'quasar'
|
import { Dialog } from 'quasar'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean;
|
modelValue: boolean;
|
||||||
domain: IDomainOwnerDisplay;
|
domain: IDomainOwnerDisplay;
|
||||||
|
dialogTitle: string;
|
||||||
|
userListTitle: string;
|
||||||
|
shareApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise<any>;
|
||||||
|
removeSharedApi: (user: IUserDisplay, domain: IDomainOwnerDisplay) => Promise<any>;
|
||||||
|
getSharedApi: (domain: IDomainOwnerDisplay) => Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IUserDisplayWithShareRole extends IUserDisplay {
|
||||||
|
isRemoving: boolean;
|
||||||
|
role: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
@@ -69,17 +99,16 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const addLoading = ref(false);
|
const addLoading = ref(false);
|
||||||
const removingUser = ref<IUserDisplay>();
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const visible = ref(props.modelValue);
|
const visible = ref(props.modelValue);
|
||||||
|
|
||||||
const allUsers = ref<IUserDisplay[]>([]);
|
const allUsers = ref<IUserDisplayWithShareRole[]>([]);
|
||||||
const sharedUsers = ref<IUserDisplay[]>([]);
|
const sharedUsers = ref<IUserDisplayWithShareRole[]>([]);
|
||||||
const sharedUsersIdSet = new Set<number>();
|
const sharedUsersIdSet = new Set<number>();
|
||||||
|
|
||||||
const canSharedUsers = ref<IUserDisplay[]>([]);
|
const canSharedUsers = ref<IUserDisplayWithShareRole[]>([]);
|
||||||
const canSharedUserFilter = ref<IUserDisplay>();
|
const canSharedUserFilter = ref<IUserDisplayWithShareRole>();
|
||||||
const canSharedUserFilteredOptions = ref<IUserDisplay[]>([]);
|
const canSharedUserFilteredOptions = ref<IUserDisplayWithShareRole[]>([]);
|
||||||
|
|
||||||
const filterFn = (val:string, update: (cb: () => void) => void) => {
|
const filterFn = (val:string, update: (cb: () => void) => void) => {
|
||||||
update(() => {
|
update(() => {
|
||||||
@@ -99,7 +128,12 @@ watch(
|
|||||||
visible.value = newValue;
|
visible.value = newValue;
|
||||||
sharedUsers.value = [];
|
sharedUsers.value = [];
|
||||||
canSharedUserFilter.value = undefined
|
canSharedUserFilter.value = undefined
|
||||||
|
loading.value = false;
|
||||||
|
addLoading.value = false;
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
|
if (Object.keys(allUsers.value).length == 0) {
|
||||||
|
await getUsers();
|
||||||
|
}
|
||||||
await loadShared();
|
await loadShared();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +164,7 @@ const checkClose = () => {
|
|||||||
}).onCancel(() => {
|
}).onCancel(() => {
|
||||||
close();
|
close();
|
||||||
}).onOk(() => {
|
}).onOk(() => {
|
||||||
shareTo(canSharedUserFilter.value as IUserDisplay);
|
shareTo(canSharedUserFilter.value as IUserDisplayWithShareRole);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,35 +172,42 @@ const close = () => {
|
|||||||
emit('close');
|
emit('close');
|
||||||
};
|
};
|
||||||
|
|
||||||
const shareTo = async (user: IUserDisplay) => {
|
const shareTo = async (user: IUserDisplayWithShareRole) => {
|
||||||
addLoading.value = true;
|
addLoading.value = true;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await api.post(`api/domain/${user.id}?domainid=${props.domain.id}`)
|
await props.shareApi(user, props.domain);
|
||||||
await loadShared();
|
await loadShared();
|
||||||
canSharedUserFilter.value = undefined;
|
canSharedUserFilter.value = undefined;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
addLoading.value = false;
|
addLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeShareTo = async (user: IUserDisplay) => {
|
const removeShareTo = async (user: IUserDisplayWithShareRole) => {
|
||||||
removingUser.value = user;
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await api.delete(`api/domain/${props.domain.id}/${user.id}`)
|
user.isRemoving = true;
|
||||||
|
await props.removeSharedApi(user, props.domain);
|
||||||
await loadShared();
|
await loadShared();
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
removingUser.value = undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadShared = async () => {
|
const loadShared = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
sharedUsersIdSet.clear();
|
sharedUsersIdSet.clear();
|
||||||
|
|
||||||
const { data } = await api.get(`/api/domainshareduser/${props.domain.id}`);
|
const { data } = await props.getSharedApi(props.domain);
|
||||||
sharedUsers.value = data.data.map((item: IUser) => {
|
sharedUsers.value = data.data.map((item: IUser) => {
|
||||||
const val = itemToDisplay(item);
|
const val = itemToDisplay(item);
|
||||||
sharedUsersIdSet.add(val.id);
|
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;
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
});
|
}).reverse().sort((a: IUserDisplayWithShareRole, b: IUserDisplayWithShareRole) => b.role - a.role);
|
||||||
|
|
||||||
canSharedUsers.value = allUsers.value.filter((item) => !sharedUsersIdSet.has(item.id));
|
canSharedUsers.value = allUsers.value.filter((item) => !sharedUsersIdSet.has(item.id));
|
||||||
canSharedUserFilteredOptions.value = canSharedUsers.value;
|
canSharedUserFilteredOptions.value = canSharedUsers.value;
|
||||||
@@ -174,14 +215,15 @@ const loadShared = async () => {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
function isOwner(userId: number) {
|
||||||
await getUsers();
|
return userId === props.domain?.owner?.id
|
||||||
})
|
}
|
||||||
|
|
||||||
|
function isManager(userId: number) {
|
||||||
|
return false // TODO
|
||||||
|
}
|
||||||
|
|
||||||
const getUsers = async () => {
|
const getUsers = async () => {
|
||||||
if (Object.keys(allUsers.value).length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const result = await api.get(`api/v1/users`);
|
const result = await api.get(`api/v1/users`);
|
||||||
allUsers.value = result.data.data.map(itemToDisplay);
|
allUsers.value = result.data.data.map(itemToDisplay);
|
||||||
@@ -198,13 +240,16 @@ const itemToDisplay = (item: IUser) => {
|
|||||||
email: item.email,
|
email: item.email,
|
||||||
isSuperuser: item.is_superuser,
|
isSuperuser: item.is_superuser,
|
||||||
isActive: item.is_active,
|
isActive: item.is_active,
|
||||||
} as IUserDisplay
|
role: 0,
|
||||||
|
} as IUserDisplayWithShareRole
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
width: 60vw;
|
width: 700px !important;
|
||||||
|
max-width: 80vw !important;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
.q-select {
|
.q-select {
|
||||||
min-width: 0 !important;
|
min-width: 0 !important;
|
||||||
|
|||||||
56
frontend/src/components/ShareDomain/ShareManageDialog.vue
Normal file
56
frontend/src/components/ShareDomain/ShareManageDialog.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<share-domain-dialog
|
||||||
|
:dialogTitle="`「${domain.name}」のドメイン管理権限設定`"
|
||||||
|
userListTitle="ドメイン管理権限を持つユーザー"
|
||||||
|
:domain="domain"
|
||||||
|
:share-api="shareApi"
|
||||||
|
:remove-shared-api="removeSharedApi"
|
||||||
|
:get-shared-api="getSharedApi"
|
||||||
|
:model-value="modelValue"
|
||||||
|
@update:modelValue="updateModelValue"
|
||||||
|
@close="close"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps, defineEmits } from 'vue';
|
||||||
|
import ShareDomainDialog from 'components/ShareDomain/ShareDomainDialog.vue';
|
||||||
|
import { IUserDisplay } from '../../types/UserTypes';
|
||||||
|
import { IDomainOwnerDisplay } from '../../types/DomainTypes';
|
||||||
|
import { api } from 'boot/axios';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: boolean;
|
||||||
|
domain: IDomainOwnerDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
async function shareApi(user: IUserDisplay, domain: IDomainOwnerDisplay) {
|
||||||
|
return api.post(`api/managedomain`, {
|
||||||
|
userid: user.id,
|
||||||
|
domainid: domain.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeSharedApi(user: IUserDisplay, domain: IDomainOwnerDisplay) {
|
||||||
|
return api.delete(`api/managedomain/${domain.id}/${user.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSharedApi(domain: IDomainOwnerDisplay) {
|
||||||
|
return api.get(`/api/managedomainuser/${domain.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: boolean): void;
|
||||||
|
(e: 'close'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const updateModelValue = (value: boolean) => {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
emit('close');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
56
frontend/src/components/ShareDomain/ShareUsageDialog.vue
Normal file
56
frontend/src/components/ShareDomain/ShareUsageDialog.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<share-domain-dialog
|
||||||
|
:dialogTitle="`「${domain.name}」のドメイン利用権限設定`"
|
||||||
|
userListTitle="ドメイン利用権限を持つユーザー"
|
||||||
|
:domain="domain"
|
||||||
|
:share-api="shareApi"
|
||||||
|
:remove-shared-api="removeSharedApi"
|
||||||
|
:get-shared-api="getSharedApi"
|
||||||
|
:model-value="modelValue"
|
||||||
|
@update:modelValue="updateModelValue"
|
||||||
|
@close="close"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps, defineEmits } from 'vue';
|
||||||
|
import ShareDomainDialog from 'components/ShareDomain/ShareDomainDialog.vue';
|
||||||
|
import { IUserDisplay } from '../../types/UserTypes';
|
||||||
|
import { IDomainOwnerDisplay } from '../../types/DomainTypes';
|
||||||
|
import { api } from 'boot/axios';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: boolean;
|
||||||
|
domain: IDomainOwnerDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
async function shareApi(user: IUserDisplay, domain: IDomainOwnerDisplay) {
|
||||||
|
return api.post(`api/userdomain`, {
|
||||||
|
userid: user.id,
|
||||||
|
domainid: domain.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeSharedApi(user: IUserDisplay, domain: IDomainOwnerDisplay) {
|
||||||
|
return api.delete(`api/domain/${domain.id}/${user.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSharedApi(domain: IDomainOwnerDisplay) {
|
||||||
|
return api.get(`/api/domainshareduser/${domain.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: boolean): void;
|
||||||
|
(e: 'close'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const updateModelValue = (value: boolean) => {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
emit('close');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -10,10 +10,17 @@
|
|||||||
</q-input>
|
</q-input>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:body-cell-actions="props">
|
<template v-for="col in columns" :key="col.name" v-slot:[`body-cell-${col.name}`]="props">
|
||||||
<q-td :props="props">
|
<slot :name="`body-cell-${col.name}`" :row="props.row" :column="props.col">
|
||||||
<slot name="actions" :row="props.row"></slot>
|
<!-- 默认内容 -->
|
||||||
</q-td>
|
<q-td v-if="col.name !== 'actions'" :props="props" >
|
||||||
|
<span>{{ props.row[col.name] }}</span>
|
||||||
|
</q-td>
|
||||||
|
<!-- actions -->
|
||||||
|
<q-td v-else auto-width :props="props">
|
||||||
|
<slot name="actions" :row="props.row"></slot>
|
||||||
|
</q-td>
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</q-table>
|
</q-table>
|
||||||
</template>
|
</template>
|
||||||
@@ -37,9 +44,10 @@ const columns = [
|
|||||||
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
||||||
{ name: 'fullName', label: '名前', field: 'fullName', align: 'left', sortable: true },
|
{ name: 'fullName', label: '名前', field: 'fullName', align: 'left', sortable: true },
|
||||||
{ name: 'email', label: '電子メール', field: 'email', align: 'left', sortable: true },
|
{ name: 'email', label: '電子メール', field: 'email', align: 'left', sortable: true },
|
||||||
|
{ name: 'role', label: '', field: 'role', align: 'left', sortable: false },
|
||||||
{ name: 'actions', label: '', field: 'actions', sortable: false },
|
{ name: 'actions', label: '', field: 'actions', sortable: false },
|
||||||
];
|
];
|
||||||
|
|
||||||
const filter = ref('');
|
const filter = ref('');
|
||||||
const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 10 });
|
const pagination = ref({ rowsPerPage: 10 });
|
||||||
</script>
|
</script>
|
||||||
@@ -6,9 +6,10 @@
|
|||||||
<div class="text-h6 ellipsis">{{ item.name }}</div>
|
<div class="text-h6 ellipsis">{{ item.name }}</div>
|
||||||
<div class="text-subtitle2">{{ item.url }}</div>
|
<div class="text-subtitle2">{{ item.url }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isOwnerFunc(item.owner.id)" class="col-auto">
|
<div class="col-auto">
|
||||||
<!-- <q-badge color="secondary" text-color="white" align="middle" class="q-mb-xs" label="他人の所有" /> -->
|
<!-- <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" />
|
<q-chip v-if="!isOwnerFunc(item.owner.id)" square color="secondary" text-color="white" icon="people" label="他人の所有" size="sm" />
|
||||||
|
<q-chip v-else square color="purple" text-color="white" icon="people" label="自分" size="sm" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
<div class="text-grey-7 text-caption text-weight-medium">
|
<div class="text-grey-7 text-caption text-weight-medium">
|
||||||
所有者
|
所有者
|
||||||
</div>
|
</div>
|
||||||
<div class="smaller-font-size">{{ item.owner.fullName }}</div>
|
<div class="smaller-font-size">{{ !isOwnerFunc(item.owner.id) ? item.owner.fullName : '自分' }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|||||||
@@ -28,6 +28,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-slot:body-cell-version="p">
|
||||||
|
<q-td :props="p">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span>{{ p.row.version }}</span>
|
||||||
|
<q-badge v-if="isVersionEditing(p.row)" color="orange-7">変更あり</q-badge>
|
||||||
|
</div>
|
||||||
|
</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">
|
||||||
<table-action-menu :row="p.row" minWidth="180px" max-width="200px" :actions="actionList" />
|
<table-action-menu :row="p.row" minWidth="180px" max-width="200px" :actions="actionList" />
|
||||||
@@ -112,6 +120,11 @@ const getApps = async () => {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isVersionEditing(app:IAppDisplay) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getApps();
|
await getApps();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,9 +29,12 @@
|
|||||||
|
|
||||||
<template v-slot:body-cell-id="p">
|
<template v-slot:body-cell-id="p">
|
||||||
<q-td :props="p">
|
<q-td :props="p">
|
||||||
<div class="flex justify-between">
|
<div class="">
|
||||||
<span>{{ p.row.id }}</span>
|
<span>{{ p.row.id }}</span>
|
||||||
<q-badge v-if="p.row.id === app.version" color="primary">適用中</q-badge>
|
<span class="q-ml-md" v-if="p.row.id === app.version">
|
||||||
|
<q-badge color="primary">適用中</q-badge>
|
||||||
|
<q-badge class="q-ml-xs" v-if="isVersionEditing()" color="orange-7">変更あり</q-badge>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
@@ -54,14 +57,23 @@
|
|||||||
|
|
||||||
<q-dialog v-model="confirmDialog" persistent>
|
<q-dialog v-model="confirmDialog" persistent>
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section class="row items-center">
|
<q-card-section class="q-pb-none">
|
||||||
<q-icon name="warning" color="warning" size="2em" />
|
<q-list>
|
||||||
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
<q-item>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon name="warning" color="warning" size="2em" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<div >現在のバージョンは未保存です。</div>
|
||||||
|
<div >プルすると、上書されますので、よろしいでしょうか?</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="Cancel" color="primary" v-close-popup />
|
<q-btn flat label="キャンセル" color="primary" v-close-popup />
|
||||||
<q-btn flat label="OK" color="primary" :loading="deleteUserLoading" @click="deleteApp" />
|
<q-btn flat label="上書きする" color="primary" :loading="deleteUserLoading" @click="doChangeVersion()" />
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
@@ -132,6 +144,11 @@ const getVersions = async () => {
|
|||||||
versionLoading.value = false;
|
versionLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isVersionEditing() {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let isSuccess = getAppById();
|
let isSuccess = getAppById();
|
||||||
if (!isSuccess) {
|
if (!isSuccess) {
|
||||||
@@ -150,25 +167,26 @@ onMounted(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function changeVersion(version: IAppVersionDisplay) {
|
async function changeVersion(version: IAppVersionDisplay) {
|
||||||
// TODO
|
|
||||||
versionLoading.value = true;
|
|
||||||
target.value = version;
|
target.value = version;
|
||||||
|
if (!isVersionEditing()) {
|
||||||
|
await doChangeVersion(version);
|
||||||
|
} else {
|
||||||
|
confirmDialog.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doChangeVersion(version?: IAppVersionDisplay) {
|
||||||
|
if (!version) {
|
||||||
|
version = target.value as IAppVersionDisplay;
|
||||||
|
}
|
||||||
|
confirmDialog.value = false;
|
||||||
|
versionLoading.value = true;
|
||||||
await appStore.changeVersion(app.value, version);
|
await appStore.changeVersion(app.value, version);
|
||||||
await getApps();
|
await getApps();
|
||||||
getAppById();
|
getAppById();
|
||||||
versionLoading.value = false;
|
versionLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const deleteApp = async () => {
|
|
||||||
// if (target.value?.id) {
|
|
||||||
// deleteUserLoading.value = true;
|
|
||||||
// await appStore.deleteApp(targetRow.value)
|
|
||||||
// await getApps();
|
|
||||||
// deleteUserLoading.value = false;
|
|
||||||
// confirmDialog.value = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function toEditFlowPage() {
|
async function toEditFlowPage() {
|
||||||
store.setApp({
|
store.setApp({
|
||||||
appId: app.value.id,
|
appId: app.value.id,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<q-breadcrumbs-el icon="widgets" label="アプリ管理" to="/app" />
|
<q-breadcrumbs-el icon="widgets" label="アプリ管理" to="/app" />
|
||||||
<q-breadcrumbs-el>
|
<q-breadcrumbs-el>
|
||||||
<template v-slot>
|
<template v-slot>
|
||||||
<a class="full-width" :href="!store.appInfo?'':`${authStore.currentDomain.kintoneUrl}/k/${store.appInfo?.appId}`" target="_blank" title="Kiontoneへ">
|
<a class="full-width" :href="store.appInfo ? `${authStore.currentDomain.kintoneUrl}/k/${store.appInfo?.appId}` : ''" target="_blank" title="Kiontoneへ">
|
||||||
{{ store.appInfo?.name }}
|
{{ store.appInfo?.name }}
|
||||||
<q-icon
|
<q-icon
|
||||||
class="q-ma-xs"
|
class="q-ma-xs"
|
||||||
@@ -99,11 +99,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, onMounted } from 'vue';
|
import { ref, reactive, computed, onMounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { IActionNode, ActionNode, IActionFlow, ActionFlow, RootAction, IActionProperty } from 'src/types/ActionTypes';
|
import { IActionNode, ActionNode, IActionFlow, ActionFlow, RootAction, IActionProperty, AppInfo } from 'src/types/ActionTypes';
|
||||||
import { IAppDisplay, IManagedApp, IVersionSubmit } from 'src/types/AppTypes';
|
import { IAppDisplay, IManagedApp, IVersionSubmit } from 'src/types/AppTypes';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useFlowEditorStore } from 'stores/flowEditor';
|
import { useFlowEditorStore } from 'stores/flowEditor';
|
||||||
import { useAuthStore } from 'stores/useAuthStore';
|
import { useAuthStore } from 'stores/useAuthStore';
|
||||||
|
import { useAppStore } from 'stores/useAppStore';
|
||||||
import { api } from 'boot/axios';
|
import { api } from 'boot/axios';
|
||||||
|
|
||||||
import NodeItem from 'src/components/main/NodeItem.vue';
|
import NodeItem from 'src/components/main/NodeItem.vue';
|
||||||
@@ -119,10 +120,11 @@ const deployLoading = ref(false);
|
|||||||
const saveLoading = ref(false);
|
const saveLoading = ref(false);
|
||||||
const initLoading = ref(true);
|
const initLoading = ref(true);
|
||||||
const drawerLeft = ref(false);
|
const drawerLeft = ref(false);
|
||||||
const versionSubmit = ref<IVersionSubmit>();
|
const versionSubmit = ref<IVersionSubmit>({} as IVersionSubmit);
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const store = useFlowEditorStore();
|
const store = useFlowEditorStore();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const appDg = ref();
|
const appDg = ref();
|
||||||
@@ -262,18 +264,15 @@ const onSaveActionProps=(props:IActionProperty[])=>{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onSaveVersion = async () => {
|
const onSaveVersion = async () => {
|
||||||
versionSubmit.value = { appId: store.appInfo?.appId }
|
if (!store.appInfo) return;
|
||||||
|
versionSubmit.value = { appId: store.appInfo.appId }
|
||||||
saveVersionAction.value = true;
|
saveVersionAction.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeSaveVersionDg = async (val: 'OK'|'CANCEL') => {
|
const closeSaveVersionDg = async (val: 'OK'|'CANCEL') => {
|
||||||
if (val == 'OK') {
|
if (val == 'OK') {
|
||||||
await onSaveAllFlow();
|
await onSaveAllFlow();
|
||||||
await api.post('api/apps', {
|
await appStore.createVersion(versionSubmit.value);
|
||||||
'appid': versionSubmit.value?.appId,
|
|
||||||
'versionname': versionSubmit.value?.name,
|
|
||||||
'comment': versionSubmit.value?.comment
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,9 +394,9 @@ const onClearFilter=()=>{
|
|||||||
filter.value='';
|
filter.value='';
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
authStore.setLeftMenu(false);
|
authStore.setLeftMenu(false);
|
||||||
fetchData();
|
await fetchData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -112,28 +112,34 @@
|
|||||||
|
|
||||||
<q-dialog v-model="confirm" persistent>
|
<q-dialog v-model="confirm" persistent>
|
||||||
<q-card>
|
<q-card>
|
||||||
|
<!-- -1 loading -->
|
||||||
<q-card-section v-if="deleteLoadingState == -1" class="row items-center">
|
<q-card-section v-if="deleteLoadingState == -1" class="row items-center">
|
||||||
<q-spinner color="primary" size="2em"/>
|
<q-spinner color="primary" size="2em"/>
|
||||||
<span class="q-ml-sm">ドメイン利用権限を確認中</span>
|
<span class="q-ml-sm">ドメイン利用/管理権限を確認中</span>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section v-else-if="deleteLoadingState == 0" class="row items-center">
|
<!-- > 0 can't delete -->
|
||||||
<q-icon name="warning" color="warning" size="2em" />
|
<q-card-section v-else-if="deleteLoadingState > 0" class="row items-center">
|
||||||
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
|
||||||
</q-card-section>
|
|
||||||
<q-card-section v-else class="row items-center">
|
|
||||||
<q-icon name="error" color="negative" size="2em" />
|
<q-icon name="error" color="negative" size="2em" />
|
||||||
<span class="q-ml-sm">ドメインは使用中です。削除してもよろしいですか?</span>
|
<span class="q-ml-sm">ドメインは使用中です。削除してもよろしいですか?</span>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
<!-- 0/-2 can delete -->
|
||||||
|
<q-card-section v-else class="row items-center">
|
||||||
|
<q-icon name="warning" color="warning" size="2em" />
|
||||||
|
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="キャンセル" color="primary" v-close-popup />
|
<q-btn flat label="キャンセル" color="primary" v-close-popup />
|
||||||
<q-btn v-if="deleteLoadingState > 0" label="実行" color="primary" v-close-popup @click="openShareDg(editId)" />
|
<!-- > 0 can't delete -->
|
||||||
<q-btn flat v-else label="OK" :disabled="deleteLoadingState" color="primary" v-close-popup @click="deleteDomain()" />
|
<q-btn v-if="deleteLoadingState > 0" label="実行" color="primary" v-close-popup @click="openShareDg(SHARE_MANAGE, editId)" />
|
||||||
|
<!-- 0/-2 can delete -->
|
||||||
|
<q-btn flat v-else label="OK" :disabled="deleteLoadingState == -1" :loading="deleteLoadingState == -2" color="primary" @click="deleteDomain()" />
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
<share-domain-dialog v-model="shareDg" :domain="shareDomain" @close="closeShareDg()" />
|
<share-usage-dialog v-model="shareDg" :domain="shareDomain" @close="shareDg = false" />
|
||||||
|
<share-manage-dialog v-model="shareManageDg" :domain="shareDomain" @close="shareManageDg = false" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -142,7 +148,8 @@
|
|||||||
import { ref, onMounted, computed } 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 ShareDomainDialog from 'components/ShareDomain/ShareDomainDialog.vue';
|
import ShareUsageDialog from 'components/ShareDomain/ShareUsageDialog.vue';
|
||||||
|
import ShareManageDialog from 'components/ShareDomain/ShareManageDialog.vue';
|
||||||
import TableActionMenu from 'components/TableActionMenu.vue';
|
import TableActionMenu from 'components/TableActionMenu.vue';
|
||||||
import { IDomain, IDomainDisplay, IDomainOwnerDisplay, IDomainSubmit } from '../types/DomainTypes';
|
import { IDomain, IDomainDisplay, IDomainOwnerDisplay, IDomainSubmit } from '../types/DomainTypes';
|
||||||
|
|
||||||
@@ -171,7 +178,7 @@ const columns = [
|
|||||||
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 addEditLoading = ref(false);
|
const addEditLoading = ref(false);
|
||||||
const deleteLoadingState = ref<number>(-1); // -1: loading, 0: allow, > 0: user count
|
const deleteLoadingState = ref<number>(-1); // -2: deleteLoading, -1: loading, 0: allow, > 0: user count
|
||||||
|
|
||||||
const filter = ref('');
|
const filter = ref('');
|
||||||
const rows = ref<IDomainOwnerDisplay[]>([]);
|
const rows = ref<IDomainOwnerDisplay[]>([]);
|
||||||
@@ -191,6 +198,7 @@ const domainActive = ref(true);
|
|||||||
const isCreate = ref(true);
|
const isCreate = ref(true);
|
||||||
let editId = ref(0);
|
let editId = ref(0);
|
||||||
const shareDg = ref(false);
|
const shareDg = ref(false);
|
||||||
|
const shareManageDg = ref(false);
|
||||||
const shareDomain = ref<IDomainOwnerDisplay>({} as IDomainOwnerDisplay);
|
const shareDomain = ref<IDomainOwnerDisplay>({} as IDomainOwnerDisplay);
|
||||||
|
|
||||||
const activeOptions = [
|
const activeOptions = [
|
||||||
@@ -214,9 +222,13 @@ const activeFilterUpdate = (option: {value: number}) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHARE_USE = 'use';
|
||||||
|
const SHARE_MANAGE = 'manage';
|
||||||
|
|
||||||
const actionList = [
|
const actionList = [
|
||||||
{ label: '編集', icon: 'edit_note', action: editRow },
|
{ label: '編集', icon: 'edit_note', action: editRow },
|
||||||
{ label: '利用権限設定', icon: 'person_add_alt', action: openShareDg },
|
{ label: '利用権限設定', icon: 'person_add_alt', action: (row: IDomainOwnerDisplay) => {openShareDg(SHARE_USE, row)} },
|
||||||
|
{ label: '管理権限設定', icon: 'add_moderator', action: (row: IDomainOwnerDisplay) => {openShareDg(SHARE_MANAGE, row)} },
|
||||||
{ separator: true },
|
{ separator: true },
|
||||||
{ label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
|
{ label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
|
||||||
];
|
];
|
||||||
@@ -269,15 +281,17 @@ async function removeRow(row: IDomainOwnerDisplay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deleteDomain = () => {
|
const deleteDomain = () => {
|
||||||
|
deleteLoadingState.value = -2;
|
||||||
api.delete(`api/domain/${editId.value}`).then(({ data }) => {
|
api.delete(`api/domain/${editId.value}`).then(({ data }) => {
|
||||||
if (!data.data) {
|
if (!data.data) {
|
||||||
// TODO dialog
|
// TODO dialog
|
||||||
}
|
}
|
||||||
|
confirm.value = false;
|
||||||
|
deleteLoadingState.value = -1;
|
||||||
getDomain();
|
getDomain();
|
||||||
// authStore.setCurrentDomain();
|
// authStore.setCurrentDomain();
|
||||||
})
|
})
|
||||||
editId.value = 0; // set in removeRow()
|
editId.value = 0; // set in removeRow()
|
||||||
deleteLoadingState.value = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function editRow(row) {
|
function editRow(row) {
|
||||||
@@ -333,18 +347,18 @@ const onSubmit = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function openShareDg(row: IDomainOwnerDisplay|number) {
|
function openShareDg(type: typeof SHARE_MANAGE|typeof SHARE_USE, row: IDomainOwnerDisplay|number) {
|
||||||
if (typeof row === 'number') {
|
if (typeof row === 'number') {
|
||||||
row = rows.value.find(item => item.id === row) as IDomainOwnerDisplay;
|
row = rows.value.find(item => item.id === row) as IDomainOwnerDisplay;
|
||||||
}
|
}
|
||||||
shareDomain.value = row ;
|
shareDomain.value = row;
|
||||||
shareDg.value = true;
|
if (type === SHARE_USE) {
|
||||||
|
shareDg.value = true;
|
||||||
|
} else if (type === SHARE_MANAGE) {
|
||||||
|
shareManageDg.value = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function closeShareDg() {
|
|
||||||
shareDg.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onReset = () => {
|
const onReset = () => {
|
||||||
name.value = '';
|
name.value = '';
|
||||||
url.value = '';
|
url.value = '';
|
||||||
|
|||||||
@@ -112,7 +112,10 @@ const addUserDomainFinished = async (val: string) => {
|
|||||||
const selected = addDomainRef.value.selected;
|
const selected = addDomainRef.value.selected;
|
||||||
if (val == 'OK' && selected.length > 0) {
|
if (val == 'OK' && selected.length > 0) {
|
||||||
addUserDomainLoading.value = true;
|
addUserDomainLoading.value = true;
|
||||||
const { data } = await api.post(`api/domain/${authStore.userId}?domainid=${selected[0].id}`)
|
const { data } = await api.post(`api/userdomain`, {
|
||||||
|
userid: authStore.userId,
|
||||||
|
domainid: selected[0].id,
|
||||||
|
});
|
||||||
if (rows.value.length === 0 && data.data) {
|
if (rows.value.length === 0 && data.data) {
|
||||||
const domain = data.data;
|
const domain = data.data;
|
||||||
await authStore.setCurrentDomain({
|
await authStore.setCurrentDomain({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { api } from 'boot/axios';
|
import { api } from 'boot/axios';
|
||||||
import { IAppDisplay, IAppVersion, IAppVersionDisplay, IManagedApp } from 'src/types/AppTypes';
|
import { IAppDisplay, IAppVersion, IAppVersionDisplay, IManagedApp, IVersionSubmit } from 'src/types/AppTypes';
|
||||||
import { IUser } from 'src/types/UserTypes';
|
import { IUser } from 'src/types/UserTypes';
|
||||||
import { date, Notify } from 'quasar'
|
import { date, Notify } from 'quasar'
|
||||||
|
|
||||||
@@ -35,15 +35,6 @@ export const useAppStore = defineStore('app', {
|
|||||||
return this.apps.find((item: IAppDisplay) => item.id === id);
|
return this.apps.find((item: IAppDisplay) => item.id === id);
|
||||||
},
|
},
|
||||||
|
|
||||||
async getVersionsByAppId(app: IAppDisplay) {
|
|
||||||
const { data } = await api.get(`api/appversions/${app.id}`);
|
|
||||||
return data.data.map((item: IAppVersion) => versionToVersionDisplay(item));
|
|
||||||
},
|
|
||||||
|
|
||||||
async changeVersion(app: IAppDisplay, version: IAppVersionDisplay) {
|
|
||||||
await api.put(`api/appversions/${app.id}/${version.id}`);
|
|
||||||
},
|
|
||||||
|
|
||||||
async deleteApp(app: IAppDisplay) {
|
async deleteApp(app: IAppDisplay) {
|
||||||
try {
|
try {
|
||||||
await api.delete(`api/apps/${app.id}`);
|
await api.delete(`api/apps/${app.id}`);
|
||||||
@@ -59,6 +50,23 @@ export const useAppStore = defineStore('app', {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getVersionsByAppId(app: IAppDisplay) {
|
||||||
|
const { data } = await api.get(`api/appversions/${app.id}`);
|
||||||
|
return data.data.map((item: IAppVersion) => versionToVersionDisplay(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
async changeVersion(app: IAppDisplay, version: IAppVersionDisplay) {
|
||||||
|
await api.put(`api/appversions/${app.id}/${version.id}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
async createVersion(versionSubmit: IVersionSubmit) {
|
||||||
|
await api.post('api/apps', {
|
||||||
|
'appid': versionSubmit.appId,
|
||||||
|
'versionname': versionSubmit.name,
|
||||||
|
'comment': versionSubmit.comment
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.apps = [];
|
this.apps = [];
|
||||||
this.rowIds.clear();
|
this.rowIds.clear();
|
||||||
|
|||||||
@@ -21,12 +21,6 @@ export interface IAppDisplay{
|
|||||||
version:number;
|
version:number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVersionInfo {
|
|
||||||
id: string;
|
|
||||||
name?: string;
|
|
||||||
desc?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IVersionSubmit {
|
export interface IVersionSubmit {
|
||||||
appId: string;
|
appId: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user