Compare commits

...

45 Commits

Author SHA1 Message Date
dt
f34dec1054 Merge branch 'daitian' of https://alicorn-dev@dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into daitian-pinia 2023-09-17 23:40:51 +08:00
dt
01b64f1aba Change App Selection Component 2023-09-17 23:34:24 +08:00
dt
3367ada343 Merge branch 'daitian' of https://alicorn-dev@dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into daitian-pinia 2023-09-17 21:46:21 +08:00
dt
f4ea3eaccb Merge branch 'maxz-new-step' of https://alicorn-dev@dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into daitian 2023-09-17 21:45:34 +08:00
dt
4adb8401d6 add pinia 2023-09-17 21:44:28 +08:00
df59bff6ae ActionFlow bug fix 2023-09-17 20:21:39 +09:00
dt
fce56e43c3 add pinia 2023-09-16 11:07:32 +08:00
dt
42618602f4 Replace ItemSelector with ActionSelec 2023-09-16 10:48:08 +08:00
dt
e02131846b selected change 2023-09-15 07:02:29 +08:00
dt
2c3b27d9de style change 2023-09-15 04:04:48 +08:00
dt
6ccc833f7d Remove unnecessary components, add an action bar. 2023-09-15 03:56:17 +08:00
dt
a0ecc2eee3 flow editor assembly and modification 2023-09-13 16:13:30 +08:00
59e6d33656 右側プロパティ開くとののバグfix 2023-09-11 23:14:05 +09:00
b641c729c2 bug fix 2023-09-11 22:16:14 +09:00
142cdcda38 プロパティ属性設定連動実装 2023-09-10 01:15:40 +09:00
fc2669dabf Merge remote-tracking branch 'origin/fang' into mvp_step2_dev 2023-09-09 01:25:06 +09:00
8e095b51e3 FlowChart削除メニュー追加 2023-09-08 21:17:20 +09:00
ff03490209 UI美化 2023-09-08 20:04:34 +09:00
40cd9998d0 FlowEditor初期合体 2023-09-08 14:28:45 +09:00
973ba159b4 flowChart初期実装 2023-09-08 13:31:41 +09:00
063a5af822 add right drawer 2023-09-08 03:52:18 +00:00
dt
6a06c71104 add flow editor left component 2023-09-07 07:54:53 +08:00
cccff1d16d fang create 2023-09-06 13:02:40 +00:00
dt
100d8de54f fix extra code after merge 2023-09-06 00:16:47 +08:00
dt
7c667660c0 Merge branch 'dt' into daitian
# Conflicts:
#	frontend/src/router/routes.ts
2023-09-05 23:56:39 +08:00
daitian
4eb56372a5 add FlowEditorPage 2023-09-02 08:14:24 +08:00
daitian
16edd398be add node v20, pnpm support 2023-09-02 05:40:53 +08:00
daitian
4e08159e6d add pnpm-lock file ignore 2023-09-02 05:14:34 +08:00
7a9718a6fa flow function add 2023-08-09 13:36:09 +00:00
f597f7aa5a Merge branch 'mvp-step1' of https://dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into mvp-step1 2023-08-02 11:35:51 +00:00
0ec2b22754 App,Field,Action Select Dialogue 2023-08-02 11:35:32 +00:00
a04f7b1bd5 Updated README.md 2023-07-31 08:51:25 +00:00
2240603c2c Renamed VUE3.0コーディングルール.md to VUE3.0-coding-rule.md 2023-07-31 08:50:35 +00:00
d9a7532805 Updated README.md 2023-07-30 18:22:40 +00:00
e59f9b802b Renamed VUE3.0编程规范.md to VUE3.0コーディングルール.md 2023-07-30 18:21:51 +00:00
ad1c330231 Renamed vue3.0编程概要.md to vue3.0概要.md 2023-07-30 18:21:30 +00:00
a1905a1274 VUEコーディングルール追加 2023-07-31 03:14:31 +09:00
e515f99a44 slot test 2023-07-30 10:02:21 +00:00
d42fac9a7d component added 2023-07-30 12:35:35 +09:00
da3df6f0a7 Merge branch 'mvp-step1' of https://dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into mvp-step1 2023-07-29 22:42:09 +09:00
0bf3a1b2c8 document 追加 2023-07-29 22:41:41 +09:00
b63999c7f9 Add Dialogue 2023-07-29 13:40:36 +00:00
772ab3c6a5 Add Dialogue 2023-07-29 13:40:04 +00:00
e3c66a5bc4 document追加 2023-07-28 15:02:11 +09:00
9e510b0183 CORS追加 2023-07-26 23:51:44 +09:00
47 changed files with 4593 additions and 150 deletions

View File

@@ -27,5 +27,5 @@ class Kintone(Base):
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
type = Column(Integer, index=True, nullable=False) type = Column(Integer, index=True, nullable=False)
name = Column(String(100), nullable=False) name = Column(String(100), nullable=False)
desc = Column(String(500)) desc = Column(String)
content = Column(String(2000)) content = Column(String)

View File

@@ -10,7 +10,7 @@ from app.db import Base,engine
from app.core.auth import get_current_active_user from app.core.auth import get_current_active_user
from app.core.celery_app import celery_app from app.core.celery_app import celery_app
from app import tasks from app import tasks
from fastapi.middleware.cors import CORSMiddleware
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
@@ -18,6 +18,19 @@ app = FastAPI(
title=config.PROJECT_NAME, docs_url="/api/docs", openapi_url="/api" title=config.PROJECT_NAME, docs_url="/api/docs", openapi_url="/api"
) )
origins = [
"http://localhost:9000",
"http://localhost",
"http://localhost:8080",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# @app.middleware("http") # @app.middleware("http")
# async def db_session_middleware(request: Request, call_next): # async def db_session_middleware(request: Request, call_next):

Binary file not shown.

View File

File diff suppressed because one or more lines are too long

3
frontend/.gitignore vendored
View File

@@ -35,3 +35,6 @@ yarn-error.log*
# local .env files # local .env files
.env.local* .env.local*
# pnpm
pnpm-lock.yaml

View File

@@ -47,3 +47,7 @@ quasar build
### Customize the configuration ### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js). See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js).
## VUE3.0编程规范
1. [VUE3.0编程概要](./VUE3.0概要.md)
2. [VUE3.0编程规范](./VUE3.0-coding-rule.md)

View File

@@ -0,0 +1,241 @@
以下是一份 Vue 3 和 TypeScript 的编程规范:
**1. 组件定义**
- 推荐使用 `defineComponent` 来定义组件,以获取 TypeScript 的类型支持。
```typescript
import { defineComponent } from 'vue'
export default defineComponent({
// 组件选项
})
```
**2. 数据定义**
- 使用 `reactive` 定义响应式对象。
- 使用 `ref` 定义响应式单值。
- 使用 `computed` 定义计算属性。
```typescript
import { reactive, ref, computed } from 'vue'
const state = reactive({
count: 0,
message: 'Hello Vue 3'
})
const count = ref(0)
const doubledCount = computed(() => state.count * 2)
```
**3. 生命周期钩子**
- 使用 `onMounted``onUpdated` 等生命周期钩子,而不是 `beforeCreate``created``beforeMount``mounted``beforeUpdate``updated``beforeUnmount``unmounted`
```typescript
import { onMounted } from 'vue'
onMounted(() => {
console.log('Component is mounted.')
})
```
**4. 组件通信**
- 使用 `props``emit` 实现父子组件通信。
- 使用 `provide``inject` 实现祖先和后代组件通信。
- 不再推荐使用 `event bus` 进行任意组件间的通信,可以使用 Vuex 或者全局 `provide`/`inject` 替代。
```typescript
// 父组件
<ChildComponent @my-event="handleEvent" />
// 子组件
this.$emit('my-event', eventData)
```
**5. 异步处理**
- 使用 `async/await` 进行异步处理。
- 使用 `Suspense``async setup()` 处理异步依赖。
```typescript
import { ref, onMounted } from 'vue'
import axios from 'axios'
onMounted(async () => {
const response = await axios.get('https://api.example.com/data')
data.value = response.data
})
```
**6. Vue Router 和 Vuex**
- 使用 Vue Router 4 和 Vuex 4它们是为 Vue 3 重新设计的。
- 使用 `useRouter``useRoute` 钩子函数在组件中使用 router。
- 使用 `useStore` 钩子函数在组件中使用 Vuex store。
```typescript
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
const store = useStore()
const router = useRouter()
```
**7. 组件模板**
- 使用 `v-model` 代替 `.sync` 修饰符进行双向绑定。
- 使用 `v-for``:key` 渲染列表。
- 使用 `v-if``v-else``v-else-if` 进行条件渲染。
- 使用 `v-on` 或者 `@` 监听事件。
- 使用 `v-bind` 或者 `:` 绑定属性。
```html
<template>
<div v-if="condition">If block</div>
<div v-else>Else block</div>
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
<button @click="handleClick">Click me</button>
</template>
```
8. **使用类型注解和接口**
在 TypeScript 中,尽可能使用类型注解和接口来提供更完善的类型信息和类型检查。这将有助于发现和预防错误。
```typescript
interface User {
name: string;
age: number;
}
const user: User = {
name: 'John',
age: 30
}
```
9. **模块化和组件化**
尽可能将功能和逻辑模块化和组件化,使得代码更易于理解和维护。特别是使用 Composition API 时,可以将公共的逻辑封装成 composable 函数。
下面是一个使用 `Suspense` 和 `axios` 的示例,这个示例将会从一个 JSON Placeholder API 获取数据:
首先,我们创建一个 composable 函数,用于获取数据:
```typescript
import { ref } from 'vue'
import axios from 'axios'
export function useAsyncData(url: string) {
const data = ref(null)
const error = ref(null)
const fetchData = async () => {
try {
const response = await axios.get(url)
data.value = response.data
} catch (e) {
error.value = e
}
}
return { data, error, fetchData }
}
```
然后,我们创建一个 Vue 组件来使用这个函数:
```js
<template>
<Suspense>
<template #default>
<div v-if="error">{{ error.message }}</div>
<div v-else>{{ data }}</div>
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import { useAsyncData } from './composables/useAsyncData'
export default defineComponent({
setup() {
const { data, error, fetchData } = useAsyncData('https://jsonplaceholder.typicode.com/posts/1')
onMounted(fetchData)
return { data, error }
},
})
</script>
<style scoped>
/* 在这里添加 CSS 样式 */
</style>
```
在这个示例中,我们在 `useAsyncData` 函数中获取数据。当 `onMounted` 钩子函数被调用时(也就是当组件挂载完成后),我们开始获取数据。这个过程是异步的,因此我们在 `Suspense` 组件的 `#fallback` 插槽中显示一个 "Loading..." 的提示。一旦数据加载完成,`Suspense` 组件的 `#default` 插槽就会被渲染,并显示获取到的数据。
10. **良好的代码风格**
遵循一致的代码风格和代码质量规则,例如使用 ESLint 和 Prettier 来检查和格式化代码。
11. **单元测试和端到端测试**
对关键的组件和函数编写单元测试,对用户的主要操作路径编写端到端测试,确保功能的正确性。
12. **注释和文档**
对复杂的逻辑和函数编写注释,提供必要的项目文档,帮助其他开发者理解和使用你的代码。
13. **以下是 Vue 2 中被废弃或改变的部分API以及在 Vue 3 中的替代方案:**
| Vue 2.x | Vue 3.0 | 说明 |
| --- | --- | --- |
| `Vue.set` / `this.$set` | 响应式数据现在是默认的,无需使用这些方法 | Vue 3 的响应式系统是从头开始构建的,所有的对象和数组都是响应式的 |
| `Vue.delete` / `this.$delete` | 无需使用这些方法 | 在 Vue 3 中,你只需要使用 `delete` 操作符即可 |
| `filters` | 无对应项 | Vue 3 不再支持过滤器,建议使用计算属性或方法替代 |
| `Vue.observable` | `reactive` | 用 `reactive` 替代 `Vue.observable`,实现数据的响应式 |
| `Vue.prototype` | `app.config.globalProperties` | 在 Vue 3 中,全局 API 已经改变,`Vue.prototype` 被 `app.config.globalProperties` 替代 |
| `Vue.component`, `Vue.directive`, `Vue.mixin`, `Vue.use` | `app.component`, `app.directive`, `app.mixin`, `app.use` | 全局注册的 API 改变,如 `Vue.component` 变为 `app.component` |
| `beforeDestroy` 和 `destroyed` 生命周期钩子 | `beforeUnmount` 和 `unmounted` | 生命周期钩子名字变化,`beforeDestroy` 和 `destroyed` 分别改为 `beforeUnmount` 和 `unmounted` |
| `$on`, `$off`, `$once` | 无对应项 | Event Bus方法被移除需要用户自行实现或者使用第三方库 |
| `v-model` 在自定义组件上使用 | 需要明确的 `modelValue` 和 `update:modelValue` | Vue 3 对 `v-model` 的改动使其在自定义组件上更具灵活性 |
| `functional` 选项 | 无对应项 | Vue 3 不再支持函数式组件的写法,而是推荐使用 `render` 函数或 `setup` 函数 |
| 异步组件的 `functional` 写法 | `defineAsyncComponent` | 异步组件的创建方式更改,通过 `defineAsyncComponent` 方法创建 |
| `destroyed` 和 `beforeDestroy` 钩子函数 | `unmounted` 和 `beforeUnmount` | 生命周期钩子的名称已改为更直观的名称,以更好地表示其在组件实例生命周期中的角色 |
| `Vue.extend` | `defineComponent` | Vue 3 使用 `defineComponent` 方法定义组件,有更好的类型推断 |
注意Vue 3 对于 Options API 和 Composition API 提供了完全的支持,你可以在一个组件中混合使用这两种 API。不过为了代码的一致性和可读性建议在一个项目中选择一种 API 并坚持使用。
- **以下是 Vue 3.0 中的 Composition API 函数的基本说明,以及与 Options API 的对比**
| Composition API | 说明 | 对应的 Options API |
| --------------- | ---- | ------------------ |
| `setup` | `setup` 是一个新引入的组件选项,用于使用 Composition API。它是组件内部使用 Composition API 的入口。| 无 |
| `ref` | `ref` 函数用于创建一个响应式的数据。它接收一个参数,返回一个响应式的 Ref 对象。| `data` |
| `reactive` | `reactive` 函数用于创建一个响应式的对象。它接收一个普通对象,返回一个响应式的对象。| `data` |
| `computed` | `computed` 函数用于创建一个计算属性。它接收一个 getter 函数或者一个具有 getter 和 setter 的对象,返回一个响应式的 Ref 对象。| `computed` |
| `watch` | `watch` 函数用于响应式地跟踪和触发副作用。它接收一个响应式的源和一个执行副作用的回调函数。| `watch` |
| `watchEffect` | `watchEffect` 函数用于立即执行传入的一个函数,并响应式地追踪其依赖,并在其依赖变更时重新运行该函数。 | 无 |
| `onMounted` | `onMounted` 函数在组件被挂载时调用。它接收一个在组件挂载后执行的回调函数。 | `mounted` |
| `onUnmounted` | `onUnmounted` 函数在组件被卸载时调用。它接收一个在组件卸载后执行的回调函数。 | `beforeDestroy`/`unmounted` |
| `onUpdated` | `onUpdated` 在组件更新后调用。它接收一个在组件更新后执行的回调函数。| `updated` |
| `provide` | `provide` 函数用于在组件上定义一个可以被后代组件注入的值。它接收一个提供的键和值。 | 有,与 `provide/inject` 相似但是属性而不是函数 |
| `inject` | `inject` 函数用于在组件中注入一个由祖先组件提供的值。它接收一个注入的键。 | 有,但与 `provide/inject` 相似但是属性而不是函数 |
值得注意的是,虽然一些 Composition API 函数与 Options API 的某些选项有相似之处,但它们的工作方式和使用方式可能有所不同。在实际使用中,你需要根据具体的使用场景和需求选择合适的 API。

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="ja-jp">
<head> <head>
<title><%= productName %></title> <title><%= productName %></title>

View File

@@ -11,12 +11,14 @@
"@quasar/extras": "^1.16.4", "@quasar/extras": "^1.16.4",
"axios": "^1.4.0", "axios": "^1.4.0",
"quasar": "^2.6.0", "quasar": "^2.6.0",
"uuid": "^9.0.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0" "vue-router": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@quasar/app-vite": "^1.3.0", "@quasar/app-vite": "^1.3.0",
"@types/node": "^12.20.21", "@types/node": "^12.20.21",
"@types/uuid": "^9.0.3",
"@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0", "@typescript-eslint/parser": "^5.10.0",
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
@@ -28,8 +30,9 @@
"typescript": "^4.5.4" "typescript": "^4.5.4"
}, },
"engines": { "engines": {
"node": "^18 || ^16 || ^14.19", "node": "^20 ||^18 || ^16 || ^14.19",
"npm": ">= 6.13.4", "npm": ">= 6.13.4",
"pnpm": ">=8.6.0",
"yarn": ">= 1.21.1" "yarn": ">= 1.21.1"
} }
}, },
@@ -544,6 +547,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/uuid": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz",
"integrity": "sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==",
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.61.0", "version": "5.61.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz",
@@ -5045,6 +5054,14 @@
"node": ">= 0.4.0" "node": ">= 0.4.0"
} }
}, },
"node_modules/uuid": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/vary": { "node_modules/vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@@ -15,13 +15,16 @@
"dependencies": { "dependencies": {
"@quasar/extras": "^1.16.4", "@quasar/extras": "^1.16.4",
"axios": "^1.4.0", "axios": "^1.4.0",
"pinia": "^2.1.6",
"quasar": "^2.6.0", "quasar": "^2.6.0",
"uuid": "^9.0.0",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0" "vue-router": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@quasar/app-vite": "^1.3.0", "@quasar/app-vite": "^1.3.0",
"@types/node": "^12.20.21", "@types/node": "^12.20.21",
"@types/uuid": "^9.0.3",
"@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0", "@typescript-eslint/parser": "^5.10.0",
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
@@ -33,8 +36,9 @@
"typescript": "^4.5.4" "typescript": "^4.5.4"
}, },
"engines": { "engines": {
"node": "^18 || ^16 || ^14.19", "node": "^20 ||^18 || ^16 || ^14.19",
"npm": ">= 6.13.4", "npm": ">= 6.13.4",
"yarn": ">= 1.21.1" "yarn": ">= 1.21.1",
"pnpm": ">=8.6.0"
} }
} }

View File

View File

@@ -0,0 +1,40 @@
<template>
<div class="q-pa-md">
<q-table :title="name+'一覧'" row-key="name" :selection="type" v-model:selected="selected" :columns="columns" :rows="rows" />
</div>
</template>
<script>
import { ref,onMounted,reactive } from 'vue'
import { api } from 'boot/axios';
export default {
name: 'actionSelect',
props: {
name: String,
type: String
},
setup() {
const columns = [
{ name: 'name', required: true,label: 'アクション名',align: 'left',field: 'name',sortable: true},
{ name: 'desc', align: 'left', label: '説明', field: 'desc', sortable: true },
{ name: 'content', label: '内容', field: 'content', sortable: true }
]
const rows = reactive([])
onMounted(async () => {
await api.get('http://127.0.0.1:8000/api/kintone/2').then(res =>{
res.data.forEach((item) =>
{
rows.push({name:item.name,desc:item.desc,content:item.content});
}
)
});
});
return {
columns,
rows,
selected: ref([]),
}
},
}
</script>

View File

@@ -0,0 +1,83 @@
<template>
<div id="action1">
<q-card class="my-card">
<q-card-section class="bg-primary text-white">
<div class="text-h6">Our Changing Planet</div>
<div class="text-subtitle2">by John Doe</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn flat>設定</q-btn>
<q-btn class="del" flat @click="clickdel">削除</q-btn>
</q-card-actions>
</q-card>
<div class="next" style="display: table;width: 100%;height:40px;" @mouseenter="showAdd = true" @mouseleave="()=>{if(!showMenu) showAdd = false;}">
<div aria-hidden="false" style="display: table-row;">
<div
style="display: table-cell;background: url(&quot;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEzIDMwIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyMCA0MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5zdDB7ZmlsbDpub25lO3N0cm9rZTojNUI1QjVDO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1taXRlcmxpbWl0OjEwO30NCgkuc3Qxe2ZpbGw6IzVCNUI1Qzt9PC9zdHlsZT4NCiA8cmVjdCB4PSI5IiB3aWR0aD0iMiIgaGVpZ2h0PSIzNy45NzQiIGZpbGw9IiM1MTUxNTEiIHN0cm9rZS13aWR0aD0iNC41MDYyIi8+DQogPHBvbHlnb24gdHJhbnNmb3JtPSJtYXRyaXgoMS4xNzg1IDAgMCAxLjE3ODUgLS42MDY5MiAyMy41NDQpIiBwb2ludHM9IjEuOTI4IDQuMDY1IDguOTk5IDExLjEzNiAxNi4wNzIgNC4wNjUgMTcuNDg2IDUuNDc5IDguOTk5IDEzLjk2NCAwLjUxNSA1LjQ3OSIgZmlsbD0iIzUxNTE1MSIvPg0KPC9zdmc+DQo=&quot;) center center no-repeat;">
</div>
</div>
<div v-if="showAdd" style="display:table-row;height:inherit;position:absolute;left:50%;">
<div style="display:table-cell;">
<q-btn round size="xs" color="primary" label="+">
<q-menu v-model="showMenu">
<q-list style="min-width: 100px">
<q-item clickable v-close-popup>
<q-item-section @click="clickadd">New tab</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { ref,watch } from 'vue'
export default {
emits: [
'addaction'
],
setup(props,context) {
const showAdd = ref(false)
const showMenu = ref(false)
watch(showMenu,(newVal) =>{
console.log('3');
if(!newVal)
{
showAdd.value = false;
}
});
const clickadd = () => {
console.log('3');
context.emit('addaction');
//let oDiv1 = pdiv;
// let oDiv1 = document.getElementById('action1');
// let oDiv2 = document.createElement('div');
// if (oDiv1 !== null) {
// oDiv2.innerHTML = oDiv1?.innerHTML;
// oDiv1?.after(oDiv2);
// let oAdd = oDiv2.getElementsByClassName('next')[0];
// oAdd.addEventListener('mouseenter', mouseenter);
// oAdd.addEventListener('mouseleave', mouseleave);
// let oDel = oDiv2.getElementsByClassName('del')[0];
// oDel.addEventListener('click', clickdel);
// }
};
const clickdel = (event: Event) => {
let oBtn = event.target as Element;
oBtn.parentElement?.parentElement?.parentElement?.parentElement?.remove();
};
// window.clickadd = clickadd;
// window.clickdel = clickdel;
// window.mouseenter = mouseenter;
// window.mouseleave = mouseleave;
return {clickadd, clickdel, showAdd, showMenu }
}
}
</script>

View File

@@ -0,0 +1,41 @@
<template>
<div class="q-pa-md">
<q-table :title="name+'一覧'" :selection="type" v-model:selected="selected" :columns="columns" :rows="rows" />
</div>
</template>
<script>
import { ref,onMounted,reactive } from 'vue'
import { api } from 'boot/axios';
export default {
name: 'appSelect',
props: {
name: String,
type: String
},
setup() {
const columns = [
{ name: 'id', required: true,label: 'アプリID',align: 'left',field: 'id',sortable: true},
{ name: 'name', align: 'center', label: 'アプリ名', field: 'name', sortable: true },
{ name: 'creator', label: '作成者', field: 'creator', sortable: true },
{ name: 'createdate', label: '作成日時', field: 'createdate' }
]
const rows = reactive([])
onMounted( () => {
api.get('allapps').then(res =>{
res.data.apps.forEach((item) =>
{
rows.push({id:item.appId,name:item.name,creator:item.creator.name,createdate:item.createdAt});
}
)
});
});
return {
columns,
rows,
selected: ref([]),
}
},
}
</script>

View File

@@ -0,0 +1,47 @@
<template>
<div class="q-pa-md">
<q-table :title="name+'一覧'" row-key="name" :selection="type" v-model:selected="selected" :columns="columns" :rows="rows" />
</div>
</template>
<script>
import { ref,onMounted,reactive } from 'vue'
import { api } from 'boot/axios';
export default {
name: 'fieldSelect',
props: {
name: String,
type: String,
appId:Number
},
setup(props) {
const columns = [
{ name: 'name', required: true,label: 'フィールド名',align: 'left',field: row=>row.name,sortable: true},
{ name: 'code', label: 'フィールドコード', align: 'left',field: 'code', sortable: true },
{ name: 'type', label: 'フィールドタイプ', align: 'left',field: 'type', sortable: true }
]
const rows = reactive([])
onMounted( () => {
api.get('appfields', {
params:{
app: props.appId
}
}).then(res =>{
let fields = res.data.properties;
console.log(fields);
Object.keys(fields).forEach((key) =>
{
rows.push({name:fields[key].label,code:fields[key].code,type:fields[key].type});
}
)
});
});
return {
columns,
rows,
selected: ref([]),
}
},
}
</script>

View File

@@ -1,9 +0,0 @@
export interface Rule{
id:number;
name:string;
condtion:CondtionTree
}
export interface CondtionTree{
}

View File

@@ -0,0 +1,42 @@
<template>
<div class="q-pa-md q-gutter-sm">
<q-dialog :model-value="visible" persistent>
<q-card style="min-width: 350px">
<q-card-section>
<div class="text-h6">{{ name }}選択</div>
</q-card-section>
<q-card-section class="q-pt-none">
<slot></slot>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="確定" v-close-popup @click="CloseDialogue('OK')" />
<q-btn flat label="キャンセル" v-close-popup @click="CloseDialogue('Cancel')" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>
<script>
export default {
name: 'showDialog',
props: {
name:String,
visible: Boolean,
},
emits: [
'close'
],
setup(props, context) {
const CloseDialogue = (val) => {
context.emit('update:visible', false);
context.emit('close', val);
}
return {
CloseDialogue
}
},
}
</script>

View File

@@ -0,0 +1,29 @@
<template>
<div class="q-py-md">
<q-tree
no-connectors
selected-color="primary"
default-expand-all
:nodes="LeftDataBus.root"
v-model:selected="flowNames1"
node-key="label"
>
</q-tree>
</div>
</template>
<script setup lang="ts">
import {
LeftDataBus,
setControlPanelE,
} from 'components/flowEditor/left/DataBus';
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useFlowEditorStore } from 'stores/flowEditor';
// 应该在page中用网络请求获取值并初始化组件
// 然后在page中执行setControlPane设置databus
const store = useFlowEditorStore();
const { flowNames1 } = storeToRefs(store);
setControlPanelE();
</script>

View File

@@ -0,0 +1,72 @@
import { reactive } from 'vue'
export const LeftDataBus = reactive<LeftData>({})
const defaultData = {
root: [
{
label: 'レコードを追加画面',
children: [
{
label: '追加画面表示した時',
header: 'rg',
value: '1-1',
group: 'g1',
children: []
},
{
label: '保存をクリックした時',
header: 'rg',
value: '1-2',
group: 'g1',
children: []
},
{
label: '保存成功した時',
header: 'rg',
value: '1-3',
group: 'g1',
children: []
},
]
},
{
label: 'レコード編集画面',
},
{
label: 'レコード詳細画面',
},
{
label: 'レコード一覧画面',
},
],
data: new Map([['g1', '1-1']])
}
export const setControlPanel = (rootData: LeftData) => {
const { root: dr, data: dd } = defaultData
LeftDataBus.title = rootData.title
LeftDataBus.root = rootData.root ?? dr
LeftDataBus.data = rootData.data ?? dd
}
export const setControlPanelE = () => {
const { root: dr, data: dd } = defaultData
// LeftDataBus.title = rootData.title
LeftDataBus.root = dr
LeftDataBus.data = dd
}
export interface LeftData {
title?: string
root?: ControlPanelData[]
data?: Map<string, string>
}
export interface ControlPanelData {
label: string,
header?: string,
value?: string,
group?: string,
children?: ControlPanelData[]
}

View File

@@ -0,0 +1,42 @@
<template>
<div
class="row"
style="
border-radius: 2px;
box-shadow: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset,
rgba(0, 0, 0, 0.3) 0px 0px 0px 1px;
"
>
<q-icon
class="self-center q-ma-sm"
name="widgets"
color="grey-9"
style="font-size: 2em"
/>
<div class="col-7 self-center ellipsis">
{{ actName }}
</div>
<div class="self-center">
<q-btn
outline
dense
label="変 更"
padding="none sm"
color="primary"
></q-btn>
</div>
</div>
</template>
<script>
import { computed } from 'vue';
export default {
props: ['actName'],
setup(props) {
const actName = computed(() => props.actName);
},
};
</script>

View File

@@ -0,0 +1,186 @@
<template>
<div class="row justify-center" :style="{ marginLeft: node.inputPoint !== '' ? '240px' : '' }" >
<div class="row">
<q-card class="action-node" :class="nodeStyle" :square="false" @click="onNodeClick" >
<q-toolbar class="col" >
<div class="text-subtitle2">{{ node.subTitle }}</div>
<q-space></q-space>
<q-btn flat round dense icon="more_horiz" size="sm" >
<q-menu auto-close anchor="top right">
<q-list>
<q-item clickable v-if="!isRoot" @click="onEditNode">
<q-item-section avatar><q-icon name="edit" ></q-icon></q-item-section>
<q-item-section >編集する</q-item-section>
</q-item>
<q-item clickable v-if="!isRoot" @click="onDeleteNode">
<q-item-section avatar><q-icon name="delete" ></q-icon></q-item-section>
<q-item-section>削除する</q-item-section>
</q-item>
<q-item clickable @click="onDeleteAllNode">
<q-item-section avatar><q-icon name="delete_sweep" ></q-icon></q-item-section>
<q-item-section >以下すべて削除する</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-toolbar>
<q-separator />
<q-card-section>
<div class="text-h7">{{ node.title }}</div>
</q-card-section>
<template v-if="hasBranch">
<q-separator />
<q-card-actions align="around">
<q-btn flat v-for="(point, index) in node.outputPoints" :key="index">
{{ point }}
</q-btn>
</q-card-actions>
</template>
</q-card>
</div>
</div>
<template v-if="hasBranch">
<div class="row justify-center" :style="{ marginLeft: node.inputPoint !== '' ? '240px' : '' }">
<div v-for="(point, index) in node.outputPoints" :key="index">
<node-line :action-node="node" :mode="getMode(point)" @addNode="addNode" :input-point="point"></node-line>
</div>
</div>
</template>
<template v-if="!hasBranch">
<div class="row justify-center" :style="{ marginLeft: node.inputPoint !== '' ? '240px' : '' }">
<node-line :action-node="node" :mode="getMode('')" @addNode="addNode" input-point=""></node-line>
</div>
</template>
</template>
<script lang="ts">
import { defineComponent, computed, ref } from 'vue';
import { IActionNode } from '../../types/ActionTypes';
import NodeLine, { Direction } from '../main/NodeLine.vue';
export default defineComponent({
name: 'NodeItem',
components: {
NodeLine
},
props: {
actionNode: {
type: Object as () => IActionNode,
required: true
},
isSelected: {
type: Boolean
}
},
emits: [
'addNode',
"nodeSelected",
"nodeEdit",
"deleteNode",
"deleteAllNextNodes",
],
setup(props, context) {
const hasBranch = computed(() => props.actionNode.outputPoints.length > 0);
const nodeStyle = computed(() => {
return {
'root-node': props.actionNode.isRoot,
'text-white': props.actionNode.isRoot,
'selected': props.isSelected && !props.actionNode.isRoot
};
});
const getMode = (point: string) => {
if (point === '' || props.actionNode.outputPoints.length === 0) {
return Direction.Default;
}
if (point === props.actionNode.outputPoints[0]) {
if (props.actionNode.nextNodeIds.get(point)) {
return Direction.Left;
} else {
return Direction.LeftNotNext;
}
} else {
if (props.actionNode.nextNodeIds.get(point)) {
return Direction.Right;
} else {
return Direction.RightNotNext;
}
}
}
/**
* アクションノード追加イベントを
* @param point 入力ポイント
*/
const addNode = (point: string) => {
context.emit('addNode', props.actionNode, point);
}
/**
* ノード選択状態
*/
const onNodeClick = () => {
context.emit('nodeSelected', props.actionNode);
}
const onEditNode=()=>{
context.emit('nodeEdit', props.actionNode);
}
/**
* ノードを削除する
*/
const onDeleteNode=()=>{
context.emit('deleteNode', props.actionNode);
}
/**
* ノードの以下すべて削除する
*/
const onDeleteAllNode=()=>{
context.emit('deleteAllNextNodes', props.actionNode);
}
return {
node: props.actionNode,
isRoot: props.actionNode.isRoot,
hasBranch,
nodeStyle,
getMode,
addNode,
onNodeClick,
onEditNode,
onDeleteNode,
onDeleteAllNode
}
}
});
</script>
<style lang="scss">
.action-node {
min-width: 300px !important;
}
.line {
height: 20px;
}
.line:after {
content: '';
background-color: $blue-7;
display: block;
width: 3px;
}
.add-icon {
font-size: 2em;
color: $blue-7;
}
.root-node {
background-color: $blue-7;
border-radius: 20px;
}
.action-node:not(.root-node):hover{
background-color: $light-blue-1;
}
.selected{
background-color: $yellow-1;
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<div>
<svg class="node-line">
<polyline :points="points.linePoints" class="line" ></polyline>
<text class="add-icon" @click="addNode(node)" :x="points.iconPoint.x" :y="points.iconPoint.y" font-family="Arial" font-size="25"
text-anchor="middle" dy=".3em" style="cursor: pointer;" >
</text>
</svg>
</div>
</template>
<script lang="ts">
import { ref, defineComponent, computed, PropType } from 'vue';
import { IActionNode, ActionNode, ActionFlow, RootAction } from '../../types/ActionTypes';
export enum Direction {
Default = "None",
Left = "LEFT",
Right = "RIGHT",
LeftNotNext = "LEFTNOTNEXT",
RightNotNext = "RIGHTNOTNEXT",
}
export default defineComponent({
name: 'NodeLine',
props: {
actionNode: {
type: Object as PropType<IActionNode>,
required: true
},
mode: {
type: String as PropType<Direction>,
required: true
},
inputPoint:{
type:String
}
},
emits: ['addNode'],
setup(props,context) {
const hasBranch = computed(() => props.actionNode.outputPoints.length > 0);
const points = computed(() => {
switch (props.mode) {
case Direction.Left:
return {
linePoints: '180, 0, 180, 40, 120, 40, 120, 60',
iconPoint: { x: 180, y: 20 }
};
case Direction.Right:
return {
linePoints: '60, 0, 60, 40, 120, 40, 120, 60',
iconPoint: { x: 60, y: 20 }
};
case Direction.LeftNotNext:
return {
linePoints: '180, 0, 180, 40',
iconPoint: { x: 180, y: 20 }
};
case Direction.RightNotNext:
return {
linePoints: '60, 0, 60, 40',
iconPoint: { x: 60, y: 30 }
};
default:
return {
linePoints: '120, 0, 120, 60',
iconPoint: { x: 120, y: 30 }
};
}
});
const addNode=(prveNode:IActionNode)=>{
context.emit('addNode',props.inputPoint);
}
return {
node: props.actionNode,
hasBranch,
points,
addNode
}
}
});
</script>
<style lang="scss">
.node-line {
height: 60px;
width: 240px;
}
.line {
stroke: $blue-7;
fill: none;
stroke-width: 2;
}
.add-icon {
stroke: $blue-8;
fill: $blue-8;
font-family: Arial;
pointer-events: all;
font-size: 2.0em;
}
.add-icon:hover{
stroke: $blue-8;
fill:$blue-8;
font-weight: bold;
font-size: 2.4em;
}
</style>

View File

@@ -32,4 +32,3 @@ export interface AppInfo {
creator?:User; creator?:User;
modifier?:User; modifier?:User;
} }

View File

@@ -0,0 +1,57 @@
<template>
<div>
<div v-for="(item, index) in componentData" :key="index">
<component :is="item.component" v-bind="item.props" v-model="item.props.modelValue"></component>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import InputText from '../right/InputText.vue';
import SelectBox from '../right/SelectBox.vue';
import DatePicker from '../right/DatePicker.vue';
import FieldInput from '../right/FieldInput.vue';
export default defineComponent({
name: 'ActionProperty',
components: {
InputText,
SelectBox,
DatePicker,
FieldInput
},
props: {
jsonData: {
type: Object,
required: true,
},
jsonValue:{
type: Object,
required: false,
}
},
computed: {
componentData() {
return this.jsonData.elements.map((element: any) => {
if(this.jsonValue != undefined )
{
if(this.jsonValue.hasOwnProperty(element.props.name))
{
element.props.modelValue = this.jsonValue[element.props.name];
}
else
{
element.props.modelValue = '';
}
}
return {
component: element.component,
props: element.props,
};
});
},
},
});
</script>

View File

@@ -0,0 +1,45 @@
<template>
<q-input v-model="selectedDate" :label="placeholder" mask="date" :rules="['date']">
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-date v-model="selectedDate">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</template>
<script lang="ts">
import { defineComponent, ref ,watchEffect} from 'vue';
export default defineComponent({
name: 'DatePicker',
props: {
placeholder: {
type: String,
default: '',
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const selectedDate = ref(props.modelValue);
watchEffect(() => {
emit('update:modelValue', selectedDate.value);
});
return {
selectedDate
};
}
});
</script>

View File

@@ -0,0 +1,62 @@
<template>
<q-input v-model="selectedField" :label="placeholder">
<template v-slot:append>
<q-icon name="search" class="cursor-pointer" @click="showDg"/>
</template>
</q-input>
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg">
<field-select ref="appDg" name="フィールド" type="single" :appId="1"></field-select>
</show-dialog>
</template>
<script lang="ts">
import { defineComponent, ref ,watchEffect} from 'vue';
import ShowDialog from '../ShowDialog.vue';
import FieldSelect from '../FieldSelect.vue';
export default defineComponent({
name: 'FieldInput',
components: {
ShowDialog,
FieldSelect,
},
props: {
placeholder: {
type: String,
default: '',
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const appDg = ref();
const show = ref(false);
const selectedField = ref(props.modelValue);
const showDg = () => {
show.value = true;
};
const closeDg = (val:string) => {
if (val == 'OK') {
selectedField.value = appDg.value.selected[0].name;
}
};
watchEffect(() => {
emit('update:modelValue', selectedField.value);
});
return {
appDg,
show,
showDg,
closeDg,
selectedField,
};
}
});
</script>

View File

@@ -0,0 +1,33 @@
<template>
<q-input :label="placeholder" v-model="inputValue"/>
</template>
<script lang="ts">
import { defineComponent,ref,watchEffect } from 'vue';
export default defineComponent({
name: 'InputText',
props: {
placeholder: {
type: String,
default: '',
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const inputValue = ref(props.modelValue);
watchEffect(() => {
emit('update:modelValue', inputValue.value);
});
return {
inputValue,
};
},
});
</script>

View File

@@ -0,0 +1,45 @@
<template>
<div>
<div v-for="(item, index) in properties" :key="index">
<component :is="item.component" v-bind="item.props" v-model="item.props.modelValue"></component>
</div>
</div>
</template>
<script lang="ts">
/**
* プロパティ属性設定生成する
*/
import { PropType, defineComponent,ref } from 'vue';
import InputText from '../right/InputText.vue';
import SelectBox from '../right/SelectBox.vue';
import DatePicker from '../right/DatePicker.vue';
import FieldInput from '../right/FieldInput.vue';
import { IActionNode,IActionProperty } from 'src/types/ActionTypes';
export default defineComponent({
name: 'PropertyList',
components: {
InputText,
SelectBox,
DatePicker,
FieldInput
},
props: {
nodeProps: {
type: Object as PropType<Array<IActionProperty>>,
required: true,
},
jsonValue:{
type: Object,
required: false,
}
},
setup(props, context) {
const properties=ref(props.nodeProps)
return {
properties
}
}
});
</script>

View File

@@ -0,0 +1,80 @@
<template>
<div class="q-pa-md q-gutter-sm">
<q-drawer
side="right"
:show-if-above="false"
bordered
:width="301"
:breakpoint="500"
class="bg-grey-3"
:model-value="showPanel"
elevated
overlay
>
<q-card class="column full-height" style="width: 300px">
<q-card-section>
<div class="text-h6">プロパティ</div>
</q-card-section>
<q-card-section class="col q-pt-none">
<property-list :node-props="actionProps" v-if="showPanel" ></property-list>
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="Save" @click="save"/>
<q-btn flat label="Cancel" @click="cancel" />
</q-card-actions>
</q-card>
</q-drawer>
</div>
</template>
<script lang="ts">
import { reactive, ref,defineComponent, defineProps,PropType ,watchEffect} from 'vue'
import PropertyList from 'components/right/PropertyList.vue';
import { IActionNode } from 'src/types/ActionTypes';
export default defineComponent({
name: 'PropertyPanel',
components: {
PropertyList
},
props: {
actionNode:{
type:Object as PropType<IActionNode>,
required:true
},
drawerRight:{
type:Boolean,
required:true
}
},
emits: [
"update:drawerRight"
],
setup(props,{emit}) {
const showPanel =ref(props.drawerRight);
const actionProps =ref(props.actionNode.actionProps);
watchEffect(() => {
showPanel.value = props.drawerRight;
actionProps.value= props.actionNode.actionProps;
});
const cancel = async() =>{
showPanel.value = false;
emit("update:drawerRight",false )
}
const save = async () =>{
showPanel.value=false;
emit("update:drawerRight",false )
}
return {
cancel,
save,
actionProps,
showPanel
}
}
});
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,36 @@
<template>
<q-select v-model="selectedValue" :label="placeholder" :options="options"/>
</template>
<script lang="ts">
import { defineComponent,ref,watchEffect } from 'vue';
export default defineComponent({
name: 'SelectBox',
props: {
placeholder: {
type: String,
default: '',
},
options: {
type: Array,
required: true,
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const selectedValue = ref(props.modelValue);
watchEffect(() => {
emit('update:modelValue', selectedValue.value);
});
return {
selectedValue
};
},
});
</script>

View File

@@ -56,10 +56,17 @@ const essentialLinks: EssentialLinkProps[] = [
target:'_self' target:'_self'
}, },
{ {
title: 'ルールエディター', title: 'フローエディター',
caption: 'rule', caption: 'flowChart',
icon: 'rule', icon: 'account_tree',
link: '/#/ruleEditor', link: '/#/flowChart',
target:'_self'
},
{
title: 'FlowEditor',
caption: 'FlowEditor',
icon: 'account_tree',
link: '/#/flowEditor',
target:'_self' target:'_self'
}, },
{ {

View File

@@ -0,0 +1,102 @@
<template>
<q-page>
<div class="flowchart">
<node-item v-for="(node,) in refFlow.actionNodes" :key="node.id"
:isSelected="node===state.activeNode" :actionNode="node"
@addNode="addNode"
@nodeSelected="onNodeSelected"
@nodeEdit="onNodeEdit"
@deleteNode="onDeleteNode"
@deleteAllNextNodes="onDeleteAllNextNodes"
></node-item>
</div>
</q-page>
<PropertyPanel :actionNode="state.activeNode" v-model:drawerRight="drawerRight"></PropertyPanel>
<show-dialog v-model:visible="showAddAction" name="アクション" @close="closeDg">
<action-select ref="appDg" name="アクション" type="single"></action-select>
</show-dialog>
</template>
<script setup lang="ts">
import {ref,reactive,computed} from 'vue';
import {IActionNode, ActionNode, IActionFlow, ActionFlow,RootAction, IActionProperty } from 'src/types/ActionTypes';
import NodeItem from 'src/components/main/NodeItem.vue';
import ShowDialog from 'components/ShowDialog.vue';
import ActionSelect from 'components/ActionSelect.vue';
import PropertyPanel from 'components/right/PropertyPanel.vue';
const rootNode:RootAction =new RootAction("app.record.create.submit","レコード追加画面","保存するとき");
const actionFlow: ActionFlow = new ActionFlow(rootNode);
const saibanProps:IActionProperty[]=[{
component:"InputText",
props:{
displayName:"フォーマット",
modelValue:"",
name:"format",
placeholder:"フォーマットを入力してください",
}
},{
component:"FieldInput",
props:{
displayName:"採番項目",
modelValue:"",
name:"field",
placeholder:"採番項目を選択してください",
}
}];
actionFlow.addNode(new ActionNode('自動採番','文書番号を自動採番する','',[],saibanProps));
actionFlow.addNode(new ActionNode('入力データ取得','電話番号を取得する',''));
const branchNode = actionFlow.addNode(new ActionNode('条件分岐','電話番号入力形式チャック','',['はい','いいえ'] ));
actionFlow.addNode(new ActionNode('入力データ取得','住所を取得する',''),branchNode,'はい');
actionFlow.addNode(new ActionNode('エラー表示','エラー表示して保存しない',''),branchNode,'いいえ' );
// ref関数を使ってtemplateとバインド
const state=reactive({
activeNode:rootNode,
})
const refFlow = ref(actionFlow);
const showAddAction=ref(false);
const drawerRight=ref(false);
const addActionNode=(action:IActionNode)=>{
refFlow.value.actionNodes.push(action);
}
const addNode=(node:IActionNode,inputPoint:string)=>{
showAddAction.value=true;
}
const onNodeSelected=(node:IActionNode)=>{
//右パネルが開いている場合、自動閉じる
if(drawerRight.value && state.activeNode.id!==node.id){
drawerRight.value=false;
}
state.activeNode = node;
}
const onNodeEdit=(node:IActionNode)=>{
state.activeNode = node;
drawerRight.value=true;
}
const onDeleteNode=(node:IActionNode)=>{
refFlow.value.removeNode(node);
}
const onDeleteAllNextNodes=(node:IActionNode)=>{
refFlow.value.removeAllNext(node.id);
}
const closeDg=(val :any)=>{
console.log("Dialog closed->",val);
}
</script>
<style lang="scss">
.flowchart{
padding-top: 10px;
}
</style>

View File

@@ -0,0 +1,122 @@
<template>
<div>
<div class="q-ma-md">
<div class="q-gutter-xs row items-start">
<q-breadcrumbs class="q-pt-xs q-mr-sm" active-color="black">
<q-breadcrumbs-el icon="home" />
<q-breadcrumbs-el :label="actName" />
<q-breadcrumbs-el
v-for="flowName in flowNames"
:key="flowName"
:label="flowName"
/>
<q-breadcrumbs-el :label="flowNames1" />
</q-breadcrumbs>
<q-separator vertical class="q-mr-xs" />
<q-btn
unelevated
class="q-py-sm"
padding="none md none sm"
color="blue-1"
text-color="primary"
size="md"
@click="drawerLeft = !drawerLeft"
label="変 更"
icon="expand_more"
dense
/>
<q-space />
<q-btn
class="q-px-sm q-mr-sm"
color="white"
size="sm"
text-color="black"
label="キャンセル"
dense
/>
<q-btn
class="q-px-sm"
color="primary"
size="sm"
label="保存する"
dense
/>
</div>
</div>
<q-layout
container
style="height: 91.5dvb"
class="shadow-2 rounded-borders"
>
<q-drawer side="left" overlay bordered v-model="drawerLeft">
<div class="q-pa-sm fixed-right">
<q-btn
flat
round
color="primary"
icon="close"
@click="drawerLeft = !drawerLeft"
/>
</div>
<div class="q-mt-lg q-pa-sm">
<q-card-section>
<div class="flex-center">
<div class="row q-pl-md">
<p class="text-h6">アクション選択</p>
</div>
<ItemSelector :actName="actName" />
</div>
</q-card-section>
</div>
<q-separator />
<div class="q-mt-md q-pa-sm">
<q-card-section>
<p class="text-h6 q-pl-md q-mb-none">フロー選択</p>
<ControlPanel />
</q-card-section>
</div>
<q-separator />
<q-card-actions align="right">
<div class="q-pa-sm">
<q-btn
flat
color="primary"
size="md"
@click="drawerLeft = !drawerLeft"
label="ジャンプ"
dense
/>
</div>
</q-card-actions>
</q-drawer>
<FlowChartTest />
</q-layout>
</div>
</template>
<script setup lang="ts">
import FlowChartTest from 'pages/FlowChartTest.vue';
import ControlPanel from 'components/flowEditor/left/ControlPanelC.vue';
import ItemSelector from 'components/flowEditor/left/ItemSelector.vue';
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useFlowEditorStore } from 'stores/flowEditor';
const actName = ref('勤怠管理 - 4');
const flowNames = ref(['レコードを追加画面', '保存をクリックした時']);
const drawerLeft = ref(false);
const store = useFlowEditorStore();
const { flowNames1 } = storeToRefs(store);
</script>
<style lang="sass"></style>

View File

@@ -9,41 +9,67 @@
</div> </div>
<div style="min-height: 100vh;"> <div style="min-height: 100vh;">
<div class="q-pa-md"> <div class="q-pa-md">
<q-btn-dropdown <q-btn-dropdown split color="primary" label="ルール新規作成" size="lg">
split <q-list>
color="primary" <q-item v-for="action in actions" clickable v-close-popup @click="onItemClick" :key="action">
label="ルール新規作成" <q-item-section>
size="lg" <q-item-label>{{ action }}</q-item-label>
> </q-item-section>
<q-list> </q-item>
<q-item </q-list>
v-for="action in actions" </q-btn-dropdown>
clickable v-close-popup </div>
@click="onItemClick" <div class="q-pa-md">
:key="action" <q-select v-model="model" :options="options" label="Standard"/>
> <q-btn :label="model+'選択'" color="primary" @click="showDg()" />
<q-item-section> <show-dialog v-model:visible="show" :name="model" @close="closeDg">
<q-item-label>{{ action }}</q-item-label> <template v-if="model=='アプリ'">
</q-item-section> <app-select ref="appDg" :name="model" type="single"></app-select>
</q-item> </template>
</q-list> <template v-if="model=='フィールド'">
</q-btn-dropdown> <field-select ref="appDg" :name="model" type="multiple" :appId="1"></field-select>
</template>
<template v-if="model=='アクション'">
<action-select ref="appDg" :name="model" type="single"></action-select>
</template>
</show-dialog>
</div> </div>
</div> </div>
</div> </div>
</q-page> </q-page>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ShowDialog from 'components/ShowDialog.vue';
import AppSelect from 'components/AppSelect.vue';
import FieldSelect from 'components/FieldSelect.vue';
import ActionSelect from 'components/ActionSelect.vue';
import { ref } from 'vue'
let show = ref(false);
let appDg = ref();
let model = ref('アプリ');
let options = ['アプリ','フィールド','アクション']
const showDg = () => {
show.value = true;
};
const closeDg = (val:string) => {
if (val == 'OK') {
alert(JSON.stringify(appDg.value.selected))
}
};
interface Props { interface Props {
title: string; title: string;
actions:string[]; actions: string[];
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
title:"ルールエディター", title: "ルールエディター",
actions:()=>["フィールド制御","一覧画面","その他"] actions: () => ["フィールド制御", "一覧画面", "その他"]
}); });
function onItemClick(evt: Event){ function onItemClick(evt: Event) {
return; return;
} }
</script> </script>

View File

@@ -0,0 +1,96 @@
<template>
<div class="q-pa-md q-gutter-sm">
<q-btn label="プロパティ" icon="keyboard_arrow_right" color="primary" @click="open('right')" />
<!-- <q-btn label="Readプロパティ" icon="keyboard_arrow_right" color="primary" @click="write('right')" /> -->
<q-dialog v-model="dialog" :position="position">
<q-card class="column full-height" style="width: 300px">
<q-card-section>
<div class="text-h6">プロパティ</div>
</q-card-section>
<q-card-section class="col q-pt-none">
<ActionProperty :jsonData="jsonData" :jsonValue="jsonValue"/>
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="Save" v-close-popup @click="save"/>
<q-btn flat label="Cancel" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>
<script setup lang="ts">
import { ref,onMounted } from 'vue'
import ActionProperty from 'components/right/ActionProperty.vue';
const dialog = ref(false)
const position = ref('top')
const jsonData = {
elements: [
{
component: 'InputText',
props: {
name:'1',
placeholder: 'Enter some text',
modelValue: '',
},
},
{
component: 'SelectBox',
props: {
name:'2',
placeholder: 'Choose an option',
modelValue: '',
options: [
'option1',
'option2',
'option3'
],
},
},
{
component: 'DatePicker',
props: {
name:'3',
placeholder: 'Choose a date',
modelValue: '',
},
},
{
component: 'FieldInput',
props: {
name:'4',
placeholder: 'Choose a field',
modelValue: '',
},
},
]
};
let jsonValue = {
1:'abc',
2:'option2',
3:'2023/09/04',
4:'6666'
};
const open = (pos:string) => {
position.value = pos
dialog.value = true
};
const save = async () =>{
jsonData.elements.forEach(property => {
if(jsonValue != undefined)
{
jsonValue[property.props.name] = property.props.modelValue;
}
});
console.log(jsonValue);
}
</script>

View File

@@ -1,13 +1,88 @@
<template> <template>
<div> <q-page>
</div> <div class="q-pa-md column content-center items-center">
<div>
<q-btn label="アクション選択" color="primary" @click="showDg()" v-if="addshow" />
<show-dialog v-model:visible="show" name="アクション" @close="closeDg">
<action-select ref="appDg" name="アクション" type="single"></action-select>
</show-dialog>
</div>
<div id="action"></div>
</div>
</q-page>
</template> </template>
<script> <script setup lang="ts">
export default { import { ref } from 'vue';
import ShowDialog from 'components/ShowDialog.vue';
import ActionSelect from 'components/ActionSelect.vue';
const show = ref(false);
const addshow = ref(true);
const appDg = ref();
const showDg = () => {
show.value = true;
};
const closeDg = (val: string) => {
if (val == 'OK') {
//alert(JSON.stringify(appDg.value.selected[0].content));
let oDiv1 = document.getElementById('action');
let oDiv2 = document.createElement('div');
oDiv2.setAttribute('class', 'action');
if (oDiv1 !== null) {
oDiv2.innerHTML = appDg.value.selected[0].content;
oDiv1?.append(oDiv2);
// let oAdd = oDiv2.getElementsByClassName('next')[0];
// oAdd.addEventListener('mouseenter', mouseenter);
// oAdd.addEventListener('mouseleave', mouseleave);
// let oDel = oDiv2.getElementsByClassName('del')[0];
// oDel.addEventListener('click', clickdel);
}
if (document.getElementsByClassName('action').length > 0) {
addshow.value = false;
}
};
};
const mouseenter = (event: Event) => {
console.log('1');
let oAdd = "<div style='display: table-cell;'><button type='button' onclick='clickadd(this.parentElement.parentElement.parentElement.parentElement)'>+</button></div>";
let oDiv1 = event.target as Element
let oDivs = oDiv1?.getElementsByClassName('add');
if (oDivs.length === 0) {
let oDiv2 = document.createElement('div');
oDiv2.className = "add";
oDiv2.setAttribute("style", "display:table-row;height:inherit;position: absolute;left:calc(50% - 19px);");
oDiv2.innerHTML = oAdd;
oDiv1?.append(oDiv2);
}
};
const mouseleave = (event: Event) => {
console.log('2');
let oDiv2 = (event.target as Element)?.parentElement?.getElementsByClassName('add');
oDiv2[0]?.remove();
};
const clickadd = (pdiv: Element) => {
console.log('3');
show.value = true;
};
const clickdel = (pdiv: Element) => {
pdiv.remove();
if (document.getElementsByClassName('action').length == 0) {
addshow.value = true;
}
};
window.clickadd = clickadd;
window.clickdel = clickdel;
window.mouseenter = mouseenter;
window.mouseleave = mouseleave;
}
</script> </script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,101 @@
<template>
<div class="q-pa-md q-gutter-sm">
<q-btn label="プロパティ" icon="keyboard_arrow_right" color="primary" @click="drawerRight = !drawerRight" />
<!-- <q-btn label="Readプロパティ" icon="keyboard_arrow_right" color="primary" @click="write('right')" /> -->
<q-drawer
side="right"
v-model="drawerRight"
show-if-above
bordered
:width="301"
:breakpoint="500"
class="bg-grey-3"
>
<q-card class="column full-height" style="width: 300px">
<q-card-section>
<div class="text-h6">プロパティ</div>
</q-card-section>
<q-card-section class="col q-pt-none">
<ActionProperty :jsonData="jsonData" :jsonValue="jsonValue" v-if="drawerRight"/>
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="Save" @click="save"/>
<q-btn flat label="Cancel" @click="cancel" />
</q-card-actions>
</q-card>
</q-drawer>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import ActionProperty from 'components/right/ActionProperty.vue';
const drawerRight = ref(false);
const jsonData = {
elements: [
{
component: 'InputText',
props: {
name:'1',
placeholder: 'Enter some text',
modelValue: '',
},
},
{
component: 'SelectBox',
props: {
name:'2',
placeholder: 'Choose an option',
modelValue: '',
options: [
'option1',
'option2',
'option3'
],
},
},
{
component: 'DatePicker',
props: {
name:'3',
placeholder: 'Choose a date',
modelValue: '',
},
},
{
component: 'FieldInput',
props: {
name:'4',
placeholder: 'Choose a field',
modelValue: '',
},
},
]
};
let jsonValue = {
1:'abc',
2:'option2',
3:'2023/09/04',
4:'6666'
};
const cancel = async() =>{
drawerRight.value = false;
}
const save = async () =>{
jsonData.elements.forEach(property => {
if(jsonValue != undefined)
{
jsonValue[property.props.name] = property.props.modelValue;
}
});
console.log(jsonValue);
drawerRight.value=false;
}
</script>

View File

@@ -4,14 +4,16 @@ const routes: RouteRecordRaw[] = [
{ {
path: '/', path: '/',
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }], children: [
{ path: '', component: () => import('pages/IndexPage.vue') },
{ path: 'ruleEditor', component: () => import('pages/RuleEditor.vue') },
{ path: 'test', component: () => import('pages/testQursar.vue') },
{ path: 'flow', component: () => import('pages/testFlow.vue') },
{ path: 'flowchart', component: () => import('pages/FlowChartTest.vue') },
{ path: 'flowEditor', component: () => import('pages/FlowEditorPage.vue') },
{ path: 'right', component: () => import('pages/testRight.vue') },
],
}, },
{
path: '/ruleEditor/',
component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/RuleEditor.vue') }],
},
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it
{ {

View File

@@ -0,0 +1,25 @@
import { defineStore } from 'pinia';
export const useFlowEditorStore = defineStore('flowEditor', {
state: () => ({
counter: 0,
flowNames: [],
flowNames1: ''
}),
getters: {
doubleCount(state) {
return state.counter * 2;
}
},
actions: {
increment() {
this.counter++;
},
setDefaultFlow() {
this.counter++
}
}
});

View File

@@ -0,0 +1,32 @@
import { store } from 'quasar/wrappers'
import { createPinia } from 'pinia'
import { Router } from 'vue-router';
/*
* When adding new properties to stores, you should also
* extend the `PiniaCustomProperties` interface.
* @see https://pinia.vuejs.org/core-concepts/plugins.html#typing-new-store-properties
*/
declare module 'pinia' {
export interface PiniaCustomProperties {
readonly router: Router;
}
}
/*
* If not building with SSR mode, you can
* directly export the Store instantiation;
*
* The function below can be async too; either use
* async/await or return a Promise which resolves
* with the Store instance.
*/
export default store((/* { ssrContext } */) => {
const pinia = createPinia()
// You can add Pinia plugins here
// pinia.use(SomePiniaPlugin)
return pinia
})

10
frontend/src/stores/store-flag.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
/* eslint-disable */
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
import "quasar/dist/types/feature-flag";
declare module "quasar/dist/types/feature-flag" {
interface QuasarFeatureFlags {
store: true;
}
}

View File

@@ -0,0 +1,19 @@
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
counter: 0
}),
getters: {
doubleCount (state) {
return state.counter * 2;
}
},
actions: {
increment () {
this.counter++;
}
}
});

View File

@@ -0,0 +1,357 @@
import { v4 as uuidv4 } from 'uuid';
/**
* アクションのプロパティ定義
*/
export interface IActionProperty {
component: string;
props: {
//プロパティ名
name: string;
//プロパティ表示名
displayName:string;
placeholder: string;
//プロパティ設定値
modelValue: any;
};
}
/**
* アクションタイプ定義
*/
export interface IActionNode{
id:string;
//アクション名
name:string;
title:string;
subTitle:string;
inputPoint:string;
//出力ポイント(条件分岐以外未使用)
outputPoints:Array<string>;
//ルートアクションKintone event
isRoot:boolean;
//アクションのプロパティ定義
actionProps:Array<IActionProperty>;
//アクションのプロパティ設定値抽出
ActionValue:object
prevNodeId?: string;
nextNodeIds: Map<string, string>;
}
/**
* アクションフローの定義
*/
export interface IActionFlow {
actionNodes:Array<IActionNode>
}
/**
* アクションのプロパティ定義に基づいたクラス
*/
class ActionProperty implements IActionProperty {
component: string;
props: {
// プロパティ名
name: string;
// プロパティ表示名
displayName: string;
placeholder: string;
// プロパティ設定値
modelValue: any;
};
static defaultProperty():IActionProperty{
return new ActionProperty('InputText','displayName','表示名','表示を入力してください','');
};
constructor(
component: string,
name: string,
displayName: string,
placeholder: string,
modelValue: any
) {
this.component = component;
this.props = {
name: name,
displayName: displayName,
placeholder: placeholder,
modelValue: modelValue
};
}
}
/**
* IActionNodeの実装、RootActionNode以外のアクション定義
*/
export class ActionNode implements IActionNode {
id:string;
name: string;
title:string;
get subTitle():string{
return this.name;
};
inputPoint:string;
//出力ポイント(条件分岐以外未使用)
outputPoints:Array<string>;
actionProps: Array<IActionProperty>;
get isRoot(): boolean{
return false;
};
get ActionValue():object{
const propValue:any={};
this.actionProps.forEach((value)=>{
propValue[value.props.name]=value.props.modelValue
});
return propValue;
};
prevNodeId?: string;
nextNodeIds: Map<string, string>;
constructor(
name: string,
title:string,
inputPoint:string,
outputPoint: Array<string> = [],
actionProps: Array<IActionProperty> =[ActionProperty.defaultProperty()]
) {
this.id=uuidv4();
this.name = name;
this.title=title;
this.inputPoint=inputPoint;
this.outputPoints = outputPoint;
const defProp =ActionProperty.defaultProperty();
defProp.props.displayName=title;
this.actionProps =actionProps;
const prop = this.actionProps.find((prop)=>prop.props.name===defProp.props.name);
if(prop===undefined){
this.actionProps.unshift(defProp);
}
this.nextNodeIds=new Map<string,string>();
}
}
/**
* ルートアクション定義
*/
export class RootAction implements IActionNode {
id:string;
name: string;
title:string;
subTitle:string;
inputPoint:string;
//出力ポイント(条件分岐以外未使用)
outputPoints:Array<string>;
isRoot: boolean;
actionProps: Array<IActionProperty>;
ActionValue:object;
prevNodeId?: string = undefined;
nextNodeIds: Map<string, string>;
constructor(
name: string,
title:string,
subTitle:string,
) {
this.id=uuidv4();
this.name = name;
this.title=title;
this.subTitle=subTitle;
this.inputPoint='';
this.outputPoints = [];
this.isRoot = true;
this.actionProps=[];
this.ActionValue={};
this.nextNodeIds=new Map<string,string>();
}
}
/**
* アクションフローの定義
*/
export class ActionFlow implements IActionFlow {
actionNodes:Array<IActionNode>;
constructor(actionNodes:Array<IActionNode>|RootAction){
if(actionNodes instanceof Array){
this.actionNodes=actionNodes;
}else{
this.actionNodes=[actionNodes];
}
}
/**
* ノードを追加する
* 1.ID採番する
* 2.前のノードを関連付け
* @param newNode 新規追加するノード
* @param prevNode 前のノード
* @param inputPoint 入力ポイント
* @returns 追加されたノード
*/
addNode(
newNode:IActionNode,
prevNode?:IActionNode,
inputPoint?:string):IActionNode
{
if(inputPoint!==undefined){
newNode.inputPoint=inputPoint;
}
if(prevNode){
this.connectNodes(prevNode,newNode,inputPoint||'');
}else{
prevNode=this.actionNodes[this.actionNodes.length-1];
this.connectNodes(prevNode,newNode,inputPoint||'');
}
this.actionNodes.push(newNode);
return newNode;
}
/**
* ノードを削除する
* @param delNode
*/
removeNode(targetNode :IActionNode):boolean{
if (!targetNode ) {
return false;
}
if(targetNode.isRoot){
return false;
}
this.disconnectFromPrevNode(targetNode);
this.reconnectOrRemoveNextNodes(targetNode);
this.removeFromActionNodes(targetNode.id);
return true;
}
/***
* 目標ノードの次のノードを全部削除する
*/
removeAllNext(targetNodeId :string){
if (!targetNodeId || targetNodeId==='') {
return false;
}
const targetNode=this.findNodeById(targetNodeId);
if(!targetNode){
return false;
}
if(targetNode.nextNodeIds.size==0){
return false;
}
for (const [, id] of targetNode.nextNodeIds) {
this.removeAllNext(id);
this.removeFromActionNodes(id);
}
}
// 断开与前一个节点的连接
disconnectFromPrevNode(targetNode: IActionNode): void {
const prevNodeId = targetNode.prevNodeId;
if (prevNodeId) {
const prevNode = this.findNodeById(prevNodeId);
if (prevNode) {
for (const [key, value] of prevNode.nextNodeIds) {
if (value === targetNode.id) {
prevNode.nextNodeIds.delete(key);
}
}
}
}
}
// 从 actionNodes 数组中移除节点
private removeFromActionNodes(targetNodeId: string): void {
const index = this.actionNodes.findIndex(node => node.id === targetNodeId);
if (index > -1) {
this.actionNodes.splice(index, 1);
}
}
/**
* ノード削除時、前のノードと次のノードを接続する
* @param targetNode
*/
reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
if(!targetNode || !targetNode.prevNodeId ){
return;
}
//前のノードを取得
const prevNode = this.findNodeById(targetNode.prevNodeId);
if(!prevNode) return;
//次のノード取得
const nextNodeIds = targetNode.nextNodeIds;
if(nextNodeIds.size==0){
return;
}
//次のノード一つの場合
if(nextNodeIds.size==1){
const nextNodeId = nextNodeIds.get('');
if(!nextNodeId) return;
const nextNode = this.findNodeById(nextNodeId) ;
if(!nextNode) return;
nextNode.prevNodeId=prevNode.id;
prevNode.nextNodeIds.set(targetNode.inputPoint||'',nextNodeId);
return;
}
//二つ以上の場合
for(const [point,nextid] of nextNodeIds){
const nextNode = this.findNodeById(nextid);
if(!this.connectNodes(prevNode,nextNode,point)){
this.removeAllNext(nextid);
this.removeFromActionNodes(nextid);
}
}
}
/**
* 二つノードを接続する
* @param prevNode
* @param nextNodeId
* @param point
* @returns
*/
connectNodes(prevNode:IActionNode,nextNode:IActionNode,point:string):boolean{
if(!prevNode || !nextNode){
return false;
}
if(!nextNode) return false;
prevNode.nextNodeIds.set(point,nextNode.id);
nextNode.prevNodeId=prevNode.id;
nextNode.inputPoint=point;
return true;
}
resetNodeRelation(prevNode: IActionNode, newNode: IActionNode, inputPoint?: string) {
// 设置新节点和前节点的关联
prevNode.nextNodeIds.set(inputPoint || '', newNode.id);
newNode.prevNodeId = prevNode.id;
// 保存前节点原有的后节点ID
const originalNextNodeId = prevNode.nextNodeIds.get(inputPoint || '');
this.setNewNodeNextId(newNode,originalNextNodeId,inputPoint);
}
/**
* 後ノードと新ノードの関連付け
* @param newNode
* @param originalNextNodeId
* @param inputPoint
*/
private setNewNodeNextId(newNode: IActionNode, originalNextNodeId: string | undefined, inputPoint?: string) {
// 如果原先的后节点存在
if (originalNextNodeId) {
// 检查新节点的 outputPoints 是否包含该 inputPoint
if (newNode.outputPoints.includes(inputPoint || '')) {
newNode.nextNodeIds.set(inputPoint || '', originalNextNodeId);
} else {
// 如果不包含,选择新节点的一个 outputPoint
const alternativeOutputPoint = newNode.outputPoints.length > 0 ? newNode.outputPoints[0] : '';
newNode.nextNodeIds.set(alternativeOutputPoint, originalNextNodeId);
}
}
}
/***
* IDでActionNodeを取得する
*/
findNodeById(id: string): IActionNode | undefined {
return this.actionNodes.find((node) => node.id === id);
}
}

1075
frontend/vue3.0概要.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@
"@nodelib/fs.stat" "2.0.5" "@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9" run-parallel "^1.1.9"
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5" version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -278,6 +278,11 @@
"@types/mime" "*" "@types/mime" "*"
"@types/node" "*" "@types/node" "*"
"@types/uuid@^9.0.3":
version "9.0.3"
resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz"
integrity sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==
"@typescript-eslint/eslint-plugin@^5.10.0": "@typescript-eslint/eslint-plugin@^5.10.0":
version "5.61.0" version "5.61.0"
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz"
@@ -294,7 +299,7 @@
semver "^7.3.7" semver "^7.3.7"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.10.0": "@typescript-eslint/parser@^5.10.0":
version "5.61.0" version "5.61.0"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz"
integrity sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg== integrity sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==
@@ -362,7 +367,7 @@
"@typescript-eslint/types" "5.61.0" "@typescript-eslint/types" "5.61.0"
eslint-visitor-keys "^3.3.0" eslint-visitor-keys "^3.3.0"
"@vitejs/plugin-vue@^2.0.0 || ^3.0.0 || ^4.0.0", "@vitejs/plugin-vue@^2.2.0": "@vitejs/plugin-vue@^2.2.0":
version "2.3.4" version "2.3.4"
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz" resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz"
integrity sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg== integrity sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==
@@ -475,22 +480,12 @@ acorn-jsx@^5.3.2:
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: acorn@^8.9.0:
version "8.10.0" version "8.10.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
ajv@^6.10.0: ajv@^6.10.0, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^6.12.4:
version "6.12.6" version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -686,7 +681,7 @@ braces@^3.0.2, braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
browserslist@^4.21.5, "browserslist@>= 4.21.0": browserslist@^4.21.5:
version "4.21.9" version "4.21.9"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz"
integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==
@@ -758,7 +753,7 @@ chardet@^0.7.0:
resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0": "chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3:
version "3.5.3" version "3.5.3"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -943,27 +938,6 @@ csstype@^3.1.1:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
debug@^4.1.1:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^4.3.2:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@2.6.9: debug@2.6.9:
version "2.6.9" version "2.6.9"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
@@ -971,6 +945,13 @@ debug@2.6.9:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
deep-is@^0.1.3: deep-is@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
@@ -1063,12 +1044,107 @@ end-of-stream@^1.4.1:
dependencies: dependencies:
once "^1.4.0" once "^1.4.0"
esbuild-android-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz#414a087cb0de8db1e347ecca6c8320513de433db"
integrity sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==
esbuild-android-arm64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz#55de3bce2aab72bcd2b606da4318ad00fb9c8151"
integrity sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==
esbuild-darwin-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz#4259f23ed6b4cea2ec8a28d87b7fb9801f093754"
integrity sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==
esbuild-darwin-arm64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz#d77b4366a71d84e530ba019d540b538b295d494a"
integrity sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==
esbuild-freebsd-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz#27b6587b3639f10519c65e07219d249b01f2ad38"
integrity sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==
esbuild-freebsd-arm64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz#63c435917e566808c71fafddc600aca4d78be1ec"
integrity sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==
esbuild-linux-32@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz#c3da774143a37e7f11559b9369d98f11f997a5d9"
integrity sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==
esbuild-linux-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz#5d92b67f674e02ae0b4a9de9a757ba482115c4ae"
integrity sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==
esbuild-linux-arm64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz#dac84740516e859d8b14e1ecc478dd5241b10c93"
integrity sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==
esbuild-linux-arm@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz#b3ae7000696cd53ed95b2b458554ff543a60e106"
integrity sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==
esbuild-linux-mips64le@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz#dad10770fac94efa092b5a0643821c955a9dd385"
integrity sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==
esbuild-linux-ppc64le@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz#b68c2f8294d012a16a88073d67e976edd4850ae0"
integrity sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==
esbuild-linux-riscv64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz#608a318b8697123e44c1e185cdf6708e3df50b93"
integrity sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==
esbuild-linux-s390x@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz#c9e7791170a3295dba79b93aa452beb9838a8625"
integrity sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==
esbuild-netbsd-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz#0abd40b8c2e37fda6f5cc41a04cb2b690823d891"
integrity sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==
esbuild-openbsd-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz#4adba0b7ea7eb1428bb00d8e94c199a949b130e8"
integrity sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==
esbuild-sunos-64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz#4b8a6d97dfedda30a6e39607393c5c90ebf63891"
integrity sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==
esbuild-windows-32@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz#d31d8ca0c1d314fb1edea163685a423b62e9ac17"
integrity sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==
esbuild-windows-64@0.14.51: esbuild-windows-64@0.14.51:
version "0.14.51" version "0.14.51"
resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz" resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz"
integrity sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA== integrity sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==
esbuild@^0.14.27, esbuild@0.14.51: esbuild-windows-arm64@0.14.51:
version "0.14.51"
resolved "https://mirrors.cloud.tencent.com/npm/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz#0220d2304bfdc11bc27e19b2aaf56edf183e4ae9"
integrity sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==
esbuild@0.14.51, esbuild@^0.14.27:
version "0.14.51" version "0.14.51"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz"
integrity sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw== integrity sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==
@@ -1140,15 +1216,7 @@ eslint-scope@^5.1.1:
esrecurse "^4.3.0" esrecurse "^4.3.0"
estraverse "^4.1.1" estraverse "^4.1.1"
eslint-scope@^7.1.1: eslint-scope@^7.1.1, eslint-scope@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz"
integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-scope@^7.2.0:
version "7.2.0" version "7.2.0"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz"
integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==
@@ -1161,7 +1229,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz"
integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^6.2.0 || ^7.0.0 || ^8.0.0", eslint@^8.10.0, eslint@^8.11.0, eslint@>=6.0.0, eslint@>=7.0.0: eslint@^8.10.0:
version "8.44.0" version "8.44.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz" resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz"
integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A== integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==
@@ -1234,12 +1302,7 @@ estraverse@^4.1.1:
resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.1.0: estraverse@^5.1.0, estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
estraverse@^5.2.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
@@ -1310,7 +1373,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-glob@^3.2.9, fast-glob@3.2.12: fast-glob@3.2.12, fast-glob@^3.2.9:
version "3.2.12" version "3.2.12"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz"
integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
@@ -1441,6 +1504,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@~2.3.2:
version "2.3.3"
resolved "https://mirrors.cloud.tencent.com/npm/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
@@ -1567,7 +1635,7 @@ http-errors@2.0.0:
statuses "2.0.1" statuses "2.0.1"
toidentifier "1.0.1" toidentifier "1.0.1"
iconv-lite@^0.4.24, iconv-lite@0.4.24: iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24" version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -1605,7 +1673,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4" version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -1889,7 +1957,7 @@ micromatch@^4.0.4:
braces "^3.0.2" braces "^3.0.2"
picomatch "^2.3.1" picomatch "^2.3.1"
"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
version "1.52.0" version "1.52.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
@@ -2144,6 +2212,14 @@ 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" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pinia@^2.1.6:
version "2.1.6"
resolved "https://mirrors.cloud.tencent.com/npm/pinia/-/pinia-2.1.6.tgz#e88959f14b61c4debd9c42d0c9944e2875cbe0fa"
integrity sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
postcss-selector-parser@^6.0.9: postcss-selector-parser@^6.0.9:
version "6.0.13" version "6.0.13"
resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz"
@@ -2157,7 +2233,7 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.1.0, postcss@^8.1.10, postcss@^8.4.13: postcss@^8.1.10, postcss@^8.4.13:
version "8.4.25" version "8.4.25"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz"
integrity sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw== integrity sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==
@@ -2206,7 +2282,7 @@ qs@6.11.0:
dependencies: dependencies:
side-channel "^1.0.4" side-channel "^1.0.4"
quasar@^2.6.0, quasar@^2.8.0: quasar@^2.6.0:
version "2.12.2" version "2.12.2"
resolved "https://registry.npmjs.org/quasar/-/quasar-2.12.2.tgz" resolved "https://registry.npmjs.org/quasar/-/quasar-2.12.2.tgz"
integrity sha512-UB+J1cN6b9FrRphUuMvW1Pt1uaOPH2XJMAZagQlYzVUmltKCXQ0sby+ANgGRYa8w/tsekMySmN9QvkQ3+hYv/g== integrity sha512-UB+J1cN6b9FrRphUuMvW1Pt1uaOPH2XJMAZagQlYzVUmltKCXQ0sby+ANgGRYa8w/tsekMySmN9QvkQ3+hYv/g==
@@ -2238,20 +2314,7 @@ raw-body@2.5.1:
iconv-lite "0.4.24" iconv-lite "0.4.24"
unpipe "1.0.0" unpipe "1.0.0"
readable-stream@^2.0.0: readable-stream@^2.0.0, readable-stream@^2.0.5:
version "2.3.8"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^2.0.5:
version "2.3.8" version "2.3.8"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
@@ -2351,7 +2414,7 @@ rollup-plugin-visualizer@^5.5.4:
source-map "^0.7.4" source-map "^0.7.4"
yargs "^17.5.1" yargs "^17.5.1"
"rollup@>=2.59.0 <2.78.0", "rollup@2.x || 3.x": "rollup@>=2.59.0 <2.78.0":
version "2.77.3" version "2.77.3"
resolved "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz" resolved "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz"
integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==
@@ -2377,7 +2440,7 @@ rxjs@^7.5.5:
dependencies: dependencies:
tslib "^2.1.0" tslib "^2.1.0"
safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@5.1.2: safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2" version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
@@ -2392,7 +2455,7 @@ safe-buffer@5.2.1:
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sass@*, sass@1.32.12: sass@1.32.12:
version "1.32.12" version "1.32.12"
resolved "https://registry.npmjs.org/sass/-/sass-1.32.12.tgz" resolved "https://registry.npmjs.org/sass/-/sass-1.32.12.tgz"
integrity sha512-zmXn03k3hN0KaiVTjohgkg98C3UowhL1/VSGdj4/VAAiMKGQOE80PFPxFP2Kyq0OUskPKcY5lImkhBKEHlypJA== integrity sha512-zmXn03k3hN0KaiVTjohgkg98C3UowhL1/VSGdj4/VAAiMKGQOE80PFPxFP2Kyq0OUskPKcY5lImkhBKEHlypJA==
@@ -2524,13 +2587,6 @@ statuses@2.0.1:
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
string_decoder@^1.1.1, string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
@@ -2540,6 +2596,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0" is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1" strip-ansi "^6.0.1"
string_decoder@^1.1.1, string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1: strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
@@ -2657,7 +2720,7 @@ type-is@~1.6.18:
media-typer "0.3.0" media-typer "0.3.0"
mime-types "~2.1.24" mime-types "~2.1.24"
typescript@^4.5.4, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": typescript@^4.5.4:
version "4.9.5" version "4.9.5"
resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
@@ -2672,7 +2735,7 @@ universalify@^2.0.0:
resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
unpipe@~1.0.0, unpipe@1.0.0: unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
@@ -2707,12 +2770,17 @@ utils-merge@1.0.1:
resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
vary@~1.1.2: vary@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
"vite@^2.0.0 || ^3.0.0 || ^4.0.0", vite@^2.5.10, vite@^2.9.13: vite@^2.9.13:
version "2.9.16" version "2.9.16"
resolved "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz" resolved "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz"
integrity sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA== integrity sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==
@@ -2724,6 +2792,11 @@ vary@~1.1.2:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
vue-demi@>=0.14.5:
version "0.14.6"
resolved "https://mirrors.cloud.tencent.com/npm/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
vue-eslint-parser@^9.3.0: vue-eslint-parser@^9.3.0:
version "9.3.1" version "9.3.1"
resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz" resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz"
@@ -2737,14 +2810,14 @@ vue-eslint-parser@^9.3.0:
lodash "^4.17.21" lodash "^4.17.21"
semver "^7.3.6" semver "^7.3.6"
vue-router@^4.0.0, vue-router@^4.0.12: vue-router@^4.0.0:
version "4.2.4" version "4.2.4"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz" resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz"
integrity sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ== integrity sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==
dependencies: dependencies:
"@vue/devtools-api" "^6.5.0" "@vue/devtools-api" "^6.5.0"
vue@^3.0.0, vue@^3.2.0, vue@^3.2.25, vue@^3.2.29, vue@3.3.4: vue@^3.0.0:
version "3.3.4" version "3.3.4"
resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz" resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz"
integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw== integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==