Merged PR 80: BUG582:UIメッセージの改善と統一
下記の箇所修正しました。 1.画面中UIメッセージの改善と統一(アクションの説明はDBの設定のため、含まれておりません) 2.kintoneドメイン登録、ユーザー使用可能なkintoneドメイン設定画面追加 Related work items: #582
This commit is contained in:
@@ -254,7 +254,7 @@ async def userdomain_details(
|
||||
async def create_userdomain(
|
||||
request: Request,
|
||||
userid: int,
|
||||
domainids:list,
|
||||
domainids:List[int] ,
|
||||
db=Depends(get_db),
|
||||
):
|
||||
try:
|
||||
|
||||
@@ -35,6 +35,8 @@ def create_access_token(*, data: dict, expires_delta: timedelta = None):
|
||||
return encoded_jwt
|
||||
|
||||
def chacha20Encrypt(plaintext:str, key=config.KINTONE_PSW_CRYPTO_KEY):
|
||||
if plaintext is None or plaintext == '':
|
||||
return None
|
||||
nonce = os.urandom(16)
|
||||
algorithm = algorithms.ChaCha20(key, nonce)
|
||||
cipher = Cipher(algorithm, mode=None)
|
||||
|
||||
@@ -216,24 +216,19 @@ def edit_domain(
|
||||
update_data = domain.dict(exclude_unset=True)
|
||||
|
||||
for key, value in update_data.items():
|
||||
if(key != "id"):
|
||||
setattr(db_domain, key, value)
|
||||
|
||||
if key != "id" and not (key == "kintonepwd" and (value is None or value == "")):
|
||||
setattr(db_domain, key, value)
|
||||
print(str(db_domain))
|
||||
db.add(db_domain)
|
||||
db.commit()
|
||||
db.refresh(db_domain)
|
||||
return db_domain
|
||||
|
||||
def add_userdomain(db: Session, userid:int,domainids:list):
|
||||
for domainid in domainids:
|
||||
db_domain = models.UserDomain(
|
||||
userid = userid,
|
||||
domainid = domainid
|
||||
)
|
||||
db.add(db_domain)
|
||||
def add_userdomain(db: Session, userid:int,domainids:list[str]):
|
||||
dbCommits = list(map(lambda domainid: models.UserDomain(userid = userid, domainid = domainid ), domainids))
|
||||
db.bulk_save_objects(dbCommits)
|
||||
db.commit()
|
||||
db.refresh(db_domain)
|
||||
return db_domain
|
||||
return dbCommits
|
||||
|
||||
def delete_userdomain(db: Session, userid: int,domainid: int):
|
||||
db_domain = db.query(models.UserDomain).filter(and_(models.UserDomain.userid == userid,models.UserDomain.domainid == domainid)).first()
|
||||
|
||||
@@ -12,14 +12,15 @@
|
||||
"dev": "quasar dev",
|
||||
"dev:local": "set \"LOCAL=true\" && quasar dev",
|
||||
"build": "set \"SOURCE_MAP=false\" && quasar build",
|
||||
"build:dev":"set \"SOURCE_MAP=true\" && quasar build"
|
||||
|
||||
"build:dev": "set \"SOURCE_MAP=true\" && quasar build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/extras": "^1.16.4",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"axios": "^1.4.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"quasar": "^2.6.0",
|
||||
"uuid": "^9.0.0",
|
||||
"vue": "^3.0.0",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { boot } from 'quasar/wrappers';
|
||||
import axios, { AxiosInstance } from 'axios';
|
||||
import {router} from 'src/router';
|
||||
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProperties {
|
||||
$axios: AxiosInstance;
|
||||
@@ -15,30 +16,10 @@ declare module '@vue/runtime-core' {
|
||||
// good idea to move this instance creation inside of the
|
||||
// "export default () => {}" function below (which runs individually
|
||||
// for each client)
|
||||
|
||||
const api:AxiosInstance = axios.create({ baseURL: process.env.KAB_BACKEND_URL });
|
||||
const token=localStorage.getItem('token')||'';
|
||||
if(token!==''){
|
||||
api.defaults.headers["Authorization"]='Bearer ' + token;
|
||||
}
|
||||
//axios例外キャプチャー
|
||||
api.interceptors.response.use(
|
||||
(response)=>response,
|
||||
(error)=>{
|
||||
if (error.response && error.response.status === 401) {
|
||||
// 認証エラーの場合再ログインする
|
||||
console.error('(; ゚Д゚)/認証エラー(401):', error);
|
||||
localStorage.removeItem('token');
|
||||
router.replace({
|
||||
path:"/login",
|
||||
query:{redirect:router.currentRoute.value.fullPath}
|
||||
});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
)
|
||||
export default boot(({ app }) => {
|
||||
// for use inside Vue files (Options API) through this.$axios and this.$api
|
||||
|
||||
app.config.globalProperties.$axios = axios;
|
||||
// ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
|
||||
// so you won't necessarily have to import axios in each vue file
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</q-field>
|
||||
<q-field stack-label full-width label="アプリ説明">
|
||||
<q-field stack-label full-width label="アプリの説明">
|
||||
<template v-slot:control>
|
||||
<div class="self-center full-width no-outline" tabindex="0">
|
||||
{{ appinfo?.description }}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:url="uploadUrl"
|
||||
:label="title"
|
||||
:headers="headers"
|
||||
accept=".csv,.xlsx"
|
||||
accept=".xlsx"
|
||||
v-on:rejected="onRejected"
|
||||
v-on:uploaded="onUploadFinished"
|
||||
v-on:failed="onFailed"
|
||||
@@ -30,7 +30,7 @@ import { ref } from 'vue';
|
||||
// https://quasar.dev/quasar-plugins/notify#Installation
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: `CSVおよびExcelファイルを選択してください。`
|
||||
message: `Excelファイルを選択してください。`
|
||||
})
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ import { ref } from 'vue';
|
||||
|
||||
const headers = ref([{name:"Authorization",value:'Bearer ' + authStore.token}]);
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
title:"設計書から導入する(csv or excel)",
|
||||
title:"設計書から導入する(Excel)",
|
||||
uploadUrl: `${process.env.KAB_BACKEND_URL}api/v1/createappfromexcel?format=1`
|
||||
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</q-header>
|
||||
|
||||
<q-drawer
|
||||
:model-value="authStore.toggleLeftDrawer"
|
||||
:model-value="authStore.LeftDrawer"
|
||||
:show-if-above="false"
|
||||
bordered
|
||||
>
|
||||
@@ -28,7 +28,7 @@
|
||||
<q-item-label
|
||||
header
|
||||
>
|
||||
関連リンク
|
||||
メニュー
|
||||
</q-item-label>
|
||||
|
||||
<EssentialLink
|
||||
@@ -46,7 +46,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onMounted } from 'vue';
|
||||
import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue';
|
||||
import DomainSelector from 'components/DomainSelector.vue';
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
@@ -56,14 +56,14 @@ const authStore = useAuthStore();
|
||||
const essentialLinks: EssentialLinkProps[] = [
|
||||
{
|
||||
title: 'ホーム',
|
||||
caption: 'home',
|
||||
caption: '設計書から導入する',
|
||||
icon: 'home',
|
||||
link: '/',
|
||||
target:'_self'
|
||||
},
|
||||
{
|
||||
title: 'フローエディター',
|
||||
caption: 'flowChart',
|
||||
caption: 'イベントを設定する',
|
||||
icon: 'account_tree',
|
||||
link: '/#/FlowChart',
|
||||
target:'_self'
|
||||
@@ -153,6 +153,9 @@ const essentialLinks: EssentialLinkProps[] = [
|
||||
|
||||
const version = process.env.version;
|
||||
const productName = process.env.productName;
|
||||
onMounted(() => {
|
||||
authStore.toggleLeftMenu();
|
||||
});
|
||||
|
||||
function toggleLeftDrawer() {
|
||||
authStore.toggleLeftMenu();
|
||||
|
||||
@@ -1,54 +1,90 @@
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table title="Treats" :rows="rows" :columns="columns" row-key="id" selection="single" :filter="filter"
|
||||
:loading="loading" v-model:selected="selected">
|
||||
<q-table title="Treats" :rows="rows" :columns="columns" row-key="id" :filter="filter" :loading="loading">
|
||||
|
||||
<template v-slot:top>
|
||||
<q-btn color="primary" :disable="loading" label="新規" @click="addRow" />
|
||||
<q-btn class="q-ml-sm" color="primary" :disable="loading" label="編集" @click="editRow" />
|
||||
<q-btn class="q-ml-sm" color="primary" :disable="loading" label="削除" @click="removeRow" />
|
||||
<q-space />
|
||||
<q-input borderless dense debounce="300" color="primary" v-model="filter">
|
||||
<q-input borderless dense filled debounce="300" v-model="filter" placeholder="検索">
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
</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="editRow(p.row)" />
|
||||
<q-btn flat color="negative" padding="xs" size="1em" icon="delete_outline" @click="removeRow(p.row)" />
|
||||
</q-btn-group>
|
||||
</q-td>
|
||||
</template>
|
||||
|
||||
</q-table>
|
||||
|
||||
<q-dialog :model-value="show" persistent>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">Kintone Account</div>
|
||||
</q-card-section>
|
||||
<q-card style="min-width: 36em">
|
||||
<q-form class="q-gutter-md" @submit="onSubmit" autocomplete="off">
|
||||
<q-card-section>
|
||||
<div class="text-h6 q-ma-sm">Kintone Account</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-pt-none">
|
||||
<q-form class="q-gutter-md">
|
||||
<q-input filled v-model="tenantid" label="Tenant" hint="Tenant ID" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" />
|
||||
<q-card-section class="q-pt-none q-mt-none">
|
||||
<div class="q-gutter-lg">
|
||||
|
||||
<q-input filled v-model="name" label="Your name *" hint="Kintone envirment name" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" />
|
||||
|
||||
<q-input filled type="url" v-model="url" label="Kintone url" hint="Kintone domain address" lazy-rules
|
||||
:rules="[val => val && val.length > 0, isDomain || 'Please type something']" />
|
||||
<q-input filled v-model="tenantid" label="テナントID" hint="テナントIDを入力してください。" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'テナントIDを入力してください。']" />
|
||||
|
||||
<q-input filled v-model="kintoneuser" label="Login user " hint="Kintone user name" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" />
|
||||
<q-input filled v-model="name" label="環境名 *" hint="kintoneの環境名を入力してください" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'kintoneの環境名を入力してください。']" />
|
||||
|
||||
<q-input v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'" hint="Password with toggle"
|
||||
label="User password">
|
||||
<template v-slot:append>
|
||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer" @click="isPwd = !isPwd" />
|
||||
</template>
|
||||
</q-input>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn label="Save" type="submit" color="primary" @click="onSubmit" />
|
||||
<q-btn label="Cancel" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
||||
</q-card-actions>
|
||||
<q-input filled type="url" v-model="url" label="Kintone url" hint="KintoneのURLを入力してください" lazy-rules
|
||||
:rules="[val => val && val.length > 0, isDomain || 'KintoneのURLを入力してください']" />
|
||||
|
||||
<q-input filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Kintoneのログイン名を入力してください']" autocomplete="new-password" />
|
||||
|
||||
<q-input v-if="isCreate" v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'"
|
||||
hint="パスワード" label="パスワード" :disable="!isCreate" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" autocomplete="new-password">
|
||||
<template v-slot:append>
|
||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||
@click="isPwd = !isPwd" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<div class="q-gutter-y-md" v-if="!isCreate">
|
||||
<q-separator />
|
||||
|
||||
<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="resetPsw" @update:model-value="updateResetPsw" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-input v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワードを入力してください"
|
||||
label="パスワード" :disable="!resetPsw" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" autocomplete="new-password">
|
||||
<template v-slot:append>
|
||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||
@click="isPwd = !isPwd" />
|
||||
</template>
|
||||
</q-input>
|
||||
<!-- <q-btn label="asdf"/> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary q-mb-md q-mx-sm">
|
||||
<q-btn label="保存" type="submit" color="primary" />
|
||||
<q-btn label="キャンセル" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
|
||||
</q-dialog>
|
||||
@@ -56,7 +92,7 @@
|
||||
<q-dialog v-model="confirm" persistent>
|
||||
<q-card>
|
||||
<q-card-section class="row items-center">
|
||||
<q-avatar icon="confirm" color="primary" text-color="white" />
|
||||
<q-icon name="warning" color="warning" size="2em" />
|
||||
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
||||
</q-card-section>
|
||||
|
||||
@@ -73,22 +109,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive } from 'vue';
|
||||
import { api } from 'boot/axios';
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const columns = [
|
||||
{ name: 'id' },
|
||||
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
||||
{
|
||||
name: 'tenantid',
|
||||
required: true,
|
||||
label: 'Tenant',
|
||||
align: 'left',
|
||||
label: 'テナントID',
|
||||
field: row => row.tenantid,
|
||||
format: val => `${val}`,
|
||||
align: 'left',
|
||||
sortable: true
|
||||
},
|
||||
{ name: 'name', align: 'center', label: 'Name', field: 'name', sortable: true },
|
||||
{ name: 'url', align: 'left', label: 'URL', field: 'url', sortable: true },
|
||||
{ name: 'user', label: 'Account', field: 'user' },
|
||||
{ name: 'password', label: 'Password', field: 'password' }
|
||||
{ name: 'name', label: '環境名', field: 'name', align: 'left', sortable: true },
|
||||
{ name: 'url', label: 'URL', field: 'url', align: 'left', sortable: true },
|
||||
{ name: 'user', label: 'ログイン名', field: 'user', align: 'left', },
|
||||
{ name: 'actions', label: '操作', field: 'actions' }
|
||||
];
|
||||
|
||||
|
||||
@@ -97,42 +136,40 @@ const filter = ref('');
|
||||
const rows = ref([]);
|
||||
const show = ref(false);
|
||||
const confirm = ref(false);
|
||||
const selected = ref([]);
|
||||
const tenantid = ref('');
|
||||
const resetPsw = ref(false);
|
||||
|
||||
const tenantid = ref(authStore.currentDomain.id);
|
||||
const name = ref('');
|
||||
const url = ref('');
|
||||
const isPwd = ref(true);
|
||||
const kintoneuser = ref('');
|
||||
const kintonepwd = ref('');
|
||||
|
||||
const kintonepwdBK = ref('');
|
||||
const isCreate = ref(true);
|
||||
let editId = ref(0);
|
||||
|
||||
const getDomain = async () => {
|
||||
loading.value = true;
|
||||
const result= await api.get(`api/domains/1`);
|
||||
rows.value= result.data.map((item)=>{
|
||||
const result = await api.get(`api/domains/1`);
|
||||
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 }
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getDomain();
|
||||
await getDomain();
|
||||
})
|
||||
|
||||
// emulate fetching data from server
|
||||
const addRow = () => {
|
||||
editId.value
|
||||
// editId.value
|
||||
onReset();
|
||||
show.value = true;
|
||||
}
|
||||
|
||||
const removeRow = () => {
|
||||
//loading.value = true
|
||||
const removeRow = (row) => {
|
||||
confirm.value = true;
|
||||
let row = JSON.parse(JSON.stringify(selected.value[0]));
|
||||
if (selected.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
editId.value = row.id;
|
||||
}
|
||||
|
||||
@@ -141,14 +178,11 @@ const deleteDomain = () => {
|
||||
getDomain();
|
||||
})
|
||||
editId.value = 0;
|
||||
selected.value = [];
|
||||
|
||||
};
|
||||
|
||||
const editRow = () => {
|
||||
if (selected.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
let row = JSON.parse(JSON.stringify(selected.value[0]));
|
||||
const editRow = (row) => {
|
||||
isCreate.value = false
|
||||
editId.value = row.id;
|
||||
tenantid.value = row.tenantid;
|
||||
name.value = row.name;
|
||||
@@ -158,6 +192,16 @@ const editRow = () => {
|
||||
isPwd.value = true;
|
||||
show.value = true;
|
||||
};
|
||||
|
||||
const updateResetPsw = (value: boolean) => {
|
||||
if (value === true) {
|
||||
kintonepwd.value = ''
|
||||
isPwd.value = true
|
||||
} else {
|
||||
kintonepwd.value = kintonepwdBK.value
|
||||
}
|
||||
}
|
||||
|
||||
const closeDg = () => {
|
||||
show.value = false;
|
||||
onReset();
|
||||
@@ -171,7 +215,7 @@ const onSubmit = () => {
|
||||
'name': name.value,
|
||||
'url': url.value,
|
||||
'kintoneuser': kintoneuser.value,
|
||||
'kintonepwd': kintonepwd.value
|
||||
'kintonepwd': isCreate.value || resetPsw.value ? kintonepwd.value : ''
|
||||
}).then(() => {
|
||||
getDomain();
|
||||
closeDg();
|
||||
@@ -192,7 +236,7 @@ const onSubmit = () => {
|
||||
onReset();
|
||||
})
|
||||
}
|
||||
selected.value = [];
|
||||
|
||||
}
|
||||
|
||||
const onReset = () => {
|
||||
@@ -202,5 +246,7 @@ const onReset = () => {
|
||||
kintonepwd.value = '';
|
||||
isPwd.value = true;
|
||||
editId.value = 0;
|
||||
isCreate.value = true;
|
||||
resetPsw.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,127 +1,21 @@
|
||||
<!-- <template>
|
||||
<div class="q-pa-md" style="max-width: 400px">
|
||||
|
||||
<q-form
|
||||
@submit="onSubmit"
|
||||
@reset="onReset"
|
||||
class="q-gutter-md"
|
||||
>
|
||||
<q-input
|
||||
filled
|
||||
v-model="name"
|
||||
label="Your name *"
|
||||
hint="Kintone envirment name"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0 || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
filled type="url"
|
||||
v-model="url"
|
||||
label="Kintone url"
|
||||
hint="Kintone domain address"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0,isDomain || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
filled
|
||||
v-model="username"
|
||||
label="Login user "
|
||||
hint="Kintone user name"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0 || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input v-model="password" filled :type="isPwd ? 'password' : 'text'" hint="Password with toggle" label="User password">
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
:name="isPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="isPwd = !isPwd"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-toggle v-model="accept" label="Active Domain" />
|
||||
|
||||
<div>
|
||||
<q-btn label="Submit" type="submit" color="primary"/>
|
||||
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
|
||||
</div>
|
||||
</q-form>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { useQuasar } from 'quasar'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
setup () {
|
||||
const $q = useQuasar()
|
||||
|
||||
const name = ref(null)
|
||||
const age = ref(null)
|
||||
const accept = ref(false)
|
||||
const isPwd =ref(true)
|
||||
|
||||
return {
|
||||
name,
|
||||
age,
|
||||
accept,
|
||||
isPwd,
|
||||
isDomain(val) {
|
||||
const domainPattern = /^https?\/\/:([a-zA-Z] +\.){1}([a-zA-Z]+)\.([a-zA-Z]+)$/;
|
||||
return (domainPattern.test(val) || '無効なURL')
|
||||
},
|
||||
|
||||
onSubmit () {
|
||||
if (accept.value !== true) {
|
||||
$q.notify({
|
||||
color: 'red-5',
|
||||
textColor: 'white',
|
||||
icon: 'warning',
|
||||
message: 'You need to accept the license and terms first'
|
||||
})
|
||||
}
|
||||
else {
|
||||
$q.notify({
|
||||
color: 'green-4',
|
||||
textColor: 'white',
|
||||
icon: 'cloud_done',
|
||||
message: 'Submitted'
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReset () {
|
||||
name.value = null
|
||||
age.value = null
|
||||
accept.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script> -->
|
||||
|
||||
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table grid grid-header title="Domain" selection="single" :rows="rows" :columns="columns" v-model:selected="selected" row-key="name" :filter="filter" hide-header>
|
||||
<div class="q-pa-lg">
|
||||
<q-table grid grid-header title="Domain" selection="single" :rows="rows" :columns="columns"
|
||||
v-model:selected="selected" row-key="name" :filter="filter" hide-header>
|
||||
<template v-slot:top>
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
<q-btn color="primary" label="追加" @click="newDomain()" dense />
|
||||
</div>
|
||||
<div class="q-gutter-sm">
|
||||
<q-btn class="q-mx-none" color="primary" label="追加" @click="newDomain()" />
|
||||
</div>
|
||||
<q-space />
|
||||
<q-input borderless dense debounce="300" v-model="filter" placeholder="Search">
|
||||
<q-input borderless dense filled debounce="300" v-model="filter" placeholder="Search">
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
|
||||
<template v-slot:item="props">
|
||||
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
|
||||
<div class="q-pa-sm">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="q-table__grid-item-row">
|
||||
@@ -130,40 +24,49 @@ export default {
|
||||
</div>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-title">URL</div>
|
||||
<div class="q-table__grid-item-value">{{ props.row.url }}</div>
|
||||
<div class="q-table__grid-item-value" style="width: 22rem;">{{ props.row.url }}</div>
|
||||
</div>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-title">Account</div>
|
||||
<div class="q-table__grid-item-value">{{ props.row.kintoneuser }}</div>
|
||||
</div>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-value">{{isActive(props.row.id) }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat @click = "activeDomain(props.row.id)">有効</q-btn>
|
||||
<q-btn flat @click = "deleteConfirm(props.row)">削除</q-btn>
|
||||
<div style="width: 98%;">
|
||||
<div class="row items-center justify-between">
|
||||
<div class="q-table__grid-item-value"
|
||||
:class="isActive(props.row.id) === 'Active' ? 'text-positive' : 'text-negative'">{{
|
||||
isActive(props.row.id) }}</div>
|
||||
<div class="col-auto">
|
||||
<q-btn v-if="isActive(props.row.id) !== 'Active'" flat
|
||||
@click="activeDomain(props.row.id)">有効</q-btn>
|
||||
<q-btn flat @click="deleteConfirm(props.row)">削除</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<show-dialog v-model:visible="show" name="ドメイン" @close="closeDg" width="350px">
|
||||
<domain-select ref="domainDg" name="ドメイン" type="multiple"></domain-select>
|
||||
<show-dialog v-model:visible="show" name="ドメイン" @close="closeDg">
|
||||
<domain-select ref="domainDg" name="ドメイン" type="multiple"></domain-select>
|
||||
</show-dialog>
|
||||
|
||||
<q-dialog v-model="confirm" persistent>
|
||||
<q-card>
|
||||
<q-card-section class="row items-center">
|
||||
<q-avatar icon="confirm" color="primary" text-color="white" />
|
||||
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
||||
<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 = "deleteDomain()"/>
|
||||
<q-btn flat label="OK" color="primary" v-close-popup @click="deleteDomain()" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
@@ -171,40 +74,36 @@ export default {
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useQuasar } from 'quasar'
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import ShowDialog from 'components/ShowDialog.vue';
|
||||
import DomainSelect from 'components/DomainSelect.vue';
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
import { api } from 'boot/axios';
|
||||
import { domain } from 'process';
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
const domainDg = ref();
|
||||
const selected = ref([])
|
||||
|
||||
const show = ref(false);
|
||||
const confirm = ref(false)
|
||||
const filter = ref()
|
||||
|
||||
let editId = ref(0);
|
||||
let activedomainid = ref(0);
|
||||
|
||||
const columns = [
|
||||
{ name: 'id'},
|
||||
{name: 'name',required: true,label: 'Name',align: 'left',field: 'name',sortable: true},
|
||||
{ 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: 'kintonepwd' },
|
||||
{ name: 'active', field: 'active'}
|
||||
{ name: 'active', field: 'active' }
|
||||
]
|
||||
|
||||
const rows = ref([] as any[]);
|
||||
|
||||
const isActive = (id:number) =>{
|
||||
if(id == activedomainid.value)
|
||||
const isActive = (id: number) => {
|
||||
if (id == activedomainid.value)
|
||||
return "Active";
|
||||
else
|
||||
return "Inactive";
|
||||
@@ -216,55 +115,48 @@ const newDomain = () => {
|
||||
};
|
||||
|
||||
|
||||
const activeDomain = (id:number) => {
|
||||
api.put(`api/activedomain/`+ id).then(() =>{
|
||||
getDomain();
|
||||
})
|
||||
const activeDomain = (id: number) => {
|
||||
api.put(`api/activedomain/` + id).then(() => {
|
||||
getDomain();
|
||||
})
|
||||
};
|
||||
|
||||
const deleteConfirm = (row:object) => {
|
||||
const deleteConfirm = (row: object) => {
|
||||
confirm.value = true;
|
||||
editId.value = row.id;
|
||||
};
|
||||
|
||||
const deleteDomain = () => {
|
||||
api.delete(`api/domain/`+ editId.value+'/1').then(() =>{
|
||||
getDomain();
|
||||
})
|
||||
console.log(authStore.getCurrentDomain);
|
||||
|
||||
api.delete(`api/domain/${editId.value}/${authStore.userId}`).then(() => {
|
||||
getDomain();
|
||||
})
|
||||
editId.value = 0;
|
||||
};
|
||||
|
||||
const closeDg = (val:string) => {
|
||||
const closeDg = (val: string) => {
|
||||
if (val == 'OK') {
|
||||
let dodmainids =[];
|
||||
let dodmainids = [];
|
||||
let domains = JSON.parse(JSON.stringify(domainDg.value.selected));
|
||||
for(var key in domains)
|
||||
{
|
||||
for (var key in domains) {
|
||||
dodmainids.push(domains[key].id);
|
||||
}
|
||||
api.post(`api/domain`, dodmainids).then(() =>{getDomain();});
|
||||
api.post(`api/domain/${authStore.userId}`, dodmainids).then(() => { getDomain(); });
|
||||
}
|
||||
|
||||
};
|
||||
const getDomain = async () => {
|
||||
const resp = await api.get(`api/activedomain`);
|
||||
activedomainid.value = resp.data.id;
|
||||
const domainResult = await api.get(`api/domain`);
|
||||
const domains = domainResult.data as any[];
|
||||
rows.value=domains.map((item)=>{
|
||||
return { id:item.id,name: item.name, url: item.url, kintoneuser: item.kintoneuser, kintonepwd: item.kintonepwd}
|
||||
});
|
||||
const resp = await api.get(`api/activedomain`);
|
||||
activedomainid.value = resp.data.id;
|
||||
const domainResult = await api.get(`api/domain`);
|
||||
const domains = domainResult.data as any[];
|
||||
rows.value = domains.map((item) => {
|
||||
return { id: item.id, name: item.name, url: item.url, kintoneuser: item.kintoneuser, kintonepwd: item.kintonepwd }
|
||||
});
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getDomain();
|
||||
})
|
||||
|
||||
const isDomain = (val) =>{
|
||||
// const domainPattern = /^https\/\/:([a-zA-Z] +\.){1}([a-zA-Z]+)\.([a-zA-Z]+)$/;
|
||||
// return (domainPattern.test(val) || '無効なURL')
|
||||
return true;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { store } from 'quasar/wrappers'
|
||||
import { createPinia } from 'pinia'
|
||||
import { Router } from 'vue-router';
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
|
||||
/*
|
||||
* When adding new properties to stores, you should also
|
||||
@@ -23,10 +24,11 @@ declare module 'pinia' {
|
||||
*/
|
||||
|
||||
export default store((/* { ssrContext } */) => {
|
||||
const pinia = createPinia()
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
|
||||
// You can add Pinia plugins here
|
||||
// pinia.use(SomePiniaPlugin)
|
||||
|
||||
return pinia
|
||||
})
|
||||
return pinia;
|
||||
});
|
||||
|
||||
@@ -1,91 +1,97 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { api } from 'boot/axios';
|
||||
import {router} from 'src/router';
|
||||
import {IDomainInfo} from '../types/ActionTypes';
|
||||
|
||||
|
||||
export interface IUserState{
|
||||
token?:string;
|
||||
returnUrl:string;
|
||||
currentDomain:IDomainInfo;
|
||||
LeftDrawer:boolean;
|
||||
import { router } from 'src/router';
|
||||
import { IDomainInfo } from '../types/ActionTypes';
|
||||
import { jwtDecode } from 'jwt-decode';
|
||||
export interface IUserState {
|
||||
token?: string;
|
||||
returnUrl: string;
|
||||
currentDomain: IDomainInfo;
|
||||
LeftDrawer: boolean;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore({
|
||||
id: 'auth',
|
||||
state: ():IUserState =>{
|
||||
const token=localStorage.getItem('token')||'';
|
||||
if(token!==''){
|
||||
api.defaults.headers["Authorization"]='Bearer ' + token;
|
||||
export const useAuthStore = defineStore('auth', {
|
||||
state: (): IUserState => ({
|
||||
token: '',
|
||||
returnUrl: '',
|
||||
LeftDrawer: false,
|
||||
currentDomain: {} as IDomainInfo,
|
||||
userId: '',
|
||||
}),
|
||||
getters: {
|
||||
toggleLeftDrawer(): boolean {
|
||||
return this.LeftDrawer;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
toggleLeftMenu() {
|
||||
this.LeftDrawer = !this.LeftDrawer;
|
||||
},
|
||||
async login(username: string, password: string) {
|
||||
const params = new URLSearchParams();
|
||||
params.append('username', username);
|
||||
params.append('password', password);
|
||||
try {
|
||||
const result = await api.post(`api/token`, params);
|
||||
console.info(result);
|
||||
this.token = result.data.access_token;
|
||||
this.userId = jwtDecode(result.data.access_token).sub;
|
||||
api.defaults.headers['Authorization'] = 'Bearer ' + this.token;
|
||||
this.currentDomain = await this.getCurrentDomain();
|
||||
router.push(this.returnUrl || '/');
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async getCurrentDomain(): Promise<IDomainInfo> {
|
||||
const activedomain = await api.get(`api/activedomain`);
|
||||
return {
|
||||
token,
|
||||
returnUrl: '',
|
||||
LeftDrawer:false,
|
||||
currentDomain: JSON.parse(localStorage.getItem('currentDomain')||"{}")
|
||||
}
|
||||
id: activedomain.data.id,
|
||||
domainName: activedomain.data.name,
|
||||
kintoneUrl: activedomain.data.url,
|
||||
};
|
||||
},
|
||||
getters:{
|
||||
toggleLeftDrawer():boolean{
|
||||
return this.LeftDrawer;
|
||||
async getUserDomains(): Promise<IDomainInfo[]> {
|
||||
const resp = await api.get(`api/domain`);
|
||||
const domains = resp.data as any[];
|
||||
return domains.map((data) => ({
|
||||
id: data.id,
|
||||
domainName: data.name,
|
||||
kintoneUrl: data.url,
|
||||
}));
|
||||
},
|
||||
logout() {
|
||||
this.token = '';
|
||||
this.currentDomain = {} as IDomainInfo; // 清空当前域
|
||||
router.push('/login');
|
||||
},
|
||||
async setCurrentDomain(domain: IDomainInfo) {
|
||||
if (domain.id === this.currentDomain.id) {
|
||||
return;
|
||||
}
|
||||
await api.put(`api/activedomain/${domain.id}`);
|
||||
this.currentDomain = domain;
|
||||
},
|
||||
actions: {
|
||||
toggleLeftMenu(){
|
||||
this.LeftDrawer=!this.LeftDrawer;
|
||||
},
|
||||
async login(username:string, password:string) {
|
||||
const params = new URLSearchParams();
|
||||
params.append('username', username);
|
||||
params.append('password', password);
|
||||
try{
|
||||
const result = await api.post(`api/token`,params);
|
||||
console.info(result);
|
||||
this.token =result.data.access_token;
|
||||
localStorage.setItem('token', result.data.access_token);
|
||||
api.defaults.headers["Authorization"]='Bearer ' + this.token;
|
||||
this.currentDomain=await this.getCurrentDomain();
|
||||
localStorage.setItem('currentDomain',JSON.stringify(this.currentDomain));
|
||||
this.router.push(this.returnUrl || '/');
|
||||
return true;
|
||||
}catch(e)
|
||||
{
|
||||
console.info(e);
|
||||
return false;
|
||||
},
|
||||
persist: {
|
||||
afterRestore: (ctx) => {
|
||||
api.defaults.headers['Authorization'] = 'Bearer ' + ctx.store.token;
|
||||
|
||||
//axios例外キャプチャー
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response && error.response.status === 401) {
|
||||
// 認証エラーの場合再ログインする
|
||||
console.error('(; ゚Д゚)/認証エラー(401):', error);
|
||||
ctx.store.logout();
|
||||
}
|
||||
},
|
||||
async getCurrentDomain():Promise<IDomainInfo>{
|
||||
const activedomain = await api.get(`api/activedomain`);
|
||||
return {
|
||||
id:activedomain.data.id,
|
||||
domainName:activedomain.data.name,
|
||||
kintoneUrl:activedomain.data.url
|
||||
}
|
||||
},
|
||||
async getUserDomains():Promise<IDomainInfo[]>{
|
||||
const resp = await api.get(`api/domain`);
|
||||
const domains =resp.data as any[];
|
||||
return domains.map(data=>{
|
||||
return {
|
||||
id:data.id,
|
||||
domainName:data.name,
|
||||
kintoneUrl:data.url
|
||||
}
|
||||
});
|
||||
},
|
||||
logout() {
|
||||
this.token = undefined;
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('currentDomain');
|
||||
router.push('/login');
|
||||
},
|
||||
async setCurrentDomain(domain:IDomainInfo){
|
||||
if(domain.id===this.currentDomain.id){
|
||||
return;
|
||||
}
|
||||
await api.put(`api/activedomain/${domain.id}`);
|
||||
this.currentDomain=domain;
|
||||
localStorage.setItem('currentDomain',JSON.stringify(this.currentDomain));
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -194,7 +194,7 @@ export class KintoneEventManager {
|
||||
),
|
||||
new kintoneEventGroup(
|
||||
'app.record.create.show.customButtonClick',
|
||||
'ボタンをクリックした時',
|
||||
'ボタンをクリックしたとき',
|
||||
[],
|
||||
'app.record.create'
|
||||
),
|
||||
@@ -222,7 +222,7 @@ export class KintoneEventManager {
|
||||
),
|
||||
new kintoneEventGroup(
|
||||
'app.record.detail.show.customButtonClick',
|
||||
'ボタンをクリックした時',
|
||||
'ボタンをクリックしたとき',
|
||||
[],
|
||||
'app.record.detail'
|
||||
),
|
||||
@@ -256,7 +256,7 @@ export class KintoneEventManager {
|
||||
),
|
||||
new kintoneEventGroup(
|
||||
'app.record.edit.show.customButtonClick',
|
||||
'ボタンをクリックした時',
|
||||
'ボタンをクリックしたとき',
|
||||
[],
|
||||
'app.record.edit'
|
||||
),
|
||||
@@ -278,7 +278,7 @@ export class KintoneEventManager {
|
||||
'app.record.index'
|
||||
),
|
||||
new kintoneEvent(
|
||||
'インライン編集の【保存】をクリックしたとき',
|
||||
'インライン編集の保存をクリックしたとき',
|
||||
'app.record.index.edit.submit',
|
||||
'app.record.index'
|
||||
),
|
||||
@@ -295,7 +295,7 @@ export class KintoneEventManager {
|
||||
// ),
|
||||
new kintoneEventGroup(
|
||||
'app.record.index.show.customButtonClick',
|
||||
'ボタンをクリックした時',
|
||||
'ボタンをクリックしたとき',
|
||||
[],
|
||||
'app.record.index'
|
||||
),
|
||||
|
||||
@@ -283,6 +283,11 @@
|
||||
resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz"
|
||||
integrity sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==
|
||||
|
||||
"@types/web-bluetooth@^0.0.20":
|
||||
version "0.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
|
||||
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.10.0":
|
||||
version "5.61.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz"
|
||||
@@ -419,6 +424,11 @@
|
||||
resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz"
|
||||
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
|
||||
|
||||
"@vue/devtools-api@^6.6.3":
|
||||
version "6.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.3.tgz#b23a588154cba8986bba82b6e1d0248bde3fd1a0"
|
||||
integrity sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==
|
||||
|
||||
"@vue/reactivity-transform@3.3.4":
|
||||
version "3.3.4"
|
||||
resolved "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz"
|
||||
@@ -467,6 +477,28 @@
|
||||
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz"
|
||||
integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
|
||||
|
||||
"@vueuse/core@^10.9.0":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.1.tgz#15d2c0b6448d2212235b23a7ba29c27173e0c2c6"
|
||||
integrity sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==
|
||||
dependencies:
|
||||
"@types/web-bluetooth" "^0.0.20"
|
||||
"@vueuse/metadata" "10.11.1"
|
||||
"@vueuse/shared" "10.11.1"
|
||||
vue-demi ">=0.14.8"
|
||||
|
||||
"@vueuse/metadata@10.11.1":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.1.tgz#209db7bb5915aa172a87510b6de2ca01cadbd2a7"
|
||||
integrity sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==
|
||||
|
||||
"@vueuse/shared@10.11.1":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.1.tgz#62b84e3118ae6e1f3ff38f4fbe71b0c5d0f10938"
|
||||
integrity sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==
|
||||
dependencies:
|
||||
vue-demi ">=0.14.8"
|
||||
|
||||
accepts@~1.3.5, accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz"
|
||||
@@ -1830,6 +1862,11 @@ jsonfile@^6.0.1:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jwt-decode@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b"
|
||||
integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==
|
||||
|
||||
kind-of@^6.0.2:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz"
|
||||
@@ -2212,13 +2249,18 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1:
|
||||
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
pinia@^2.1.6:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz"
|
||||
integrity sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==
|
||||
pinia-plugin-persistedstate@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.1.tgz#66780602aecd6c7b152dd7e3ddc249a1f7a13fe5"
|
||||
integrity sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==
|
||||
|
||||
pinia@^2.1.7:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.2.1.tgz#7cf860f6a23981c23e58605cee45496ce46d15d1"
|
||||
integrity sha512-ltEU3xwiz5ojVMizdP93AHi84Rtfz0+yKd8ud75hr9LVyWX2alxp7vLbY1kFm7MXFmHHr/9B08Xf8Jj6IHTEiQ==
|
||||
dependencies:
|
||||
"@vue/devtools-api" "^6.5.0"
|
||||
vue-demi ">=0.14.5"
|
||||
"@vue/devtools-api" "^6.6.3"
|
||||
vue-demi "^0.14.10"
|
||||
|
||||
postcss-selector-parser@^6.0.9:
|
||||
version "6.0.13"
|
||||
@@ -2792,10 +2834,10 @@ vite@^2.9.13:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vue-demi@>=0.14.5:
|
||||
version "0.14.6"
|
||||
resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz"
|
||||
integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
|
||||
vue-demi@>=0.14.8, vue-demi@^0.14.10:
|
||||
version "0.14.10"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04"
|
||||
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
|
||||
|
||||
vue-eslint-parser@^9.3.0:
|
||||
version "9.3.1"
|
||||
|
||||
Reference in New Issue
Block a user