mirror of
https://github.com/semaphoreui/semaphore.git
synced 2025-01-07 16:42:41 +01:00
feat(ui): add formatting packages
This commit is contained in:
parent
5b82ee6587
commit
937ebb7158
@ -1,15 +1,20 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
|
||||
extends: [
|
||||
'plugin:import/recommended',
|
||||
'plugin:vue/essential',
|
||||
'@vue/airbnb',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
},
|
||||
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
@ -19,6 +24,7 @@ module.exports = {
|
||||
'vue/valid-v-slot': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
@ -30,4 +36,19 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
settings: {
|
||||
'import/extensions': ['.js', '.vue'],
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.vue', '.ts'],
|
||||
},
|
||||
alias: {
|
||||
extensions: ['.js', '.vue'],
|
||||
map: [
|
||||
['@', './src'],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
114
web/package-lock.json
generated
114
web/package-lock.json
generated
@ -34,7 +34,9 @@
|
||||
"chai": "^4.3.6",
|
||||
"dotenv": "^16.4.5",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-vue": "^9.1.1",
|
||||
"eslint-plugin-vuejs-accessibility": "^1.2.0",
|
||||
"glob-parent": ">=5.1.2",
|
||||
@ -45,6 +47,7 @@
|
||||
"nyc": "^15.1.0",
|
||||
"openai": "^4.65.0",
|
||||
"plugin-error": "^2.0.1",
|
||||
"prettier": "^3.4.2",
|
||||
"sass": "~1.81.0",
|
||||
"sass-loader": "^13.0.0",
|
||||
"stylus": "^0.64.0",
|
||||
@ -3484,6 +3487,22 @@
|
||||
"prettier": "^1.18.2 || ^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc/node_modules/prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/component-compiler-utils": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz",
|
||||
@ -3542,6 +3561,23 @@
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/component-compiler-utils/node_modules/prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/component-compiler-utils/node_modules/yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
@ -7314,6 +7350,32 @@
|
||||
"eslint-plugin-import": "^2.25.2"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-prettier": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-import-resolver-alias": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-alias/-/eslint-import-resolver-alias-1.1.2.tgz",
|
||||
"integrity": "sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint-plugin-import": ">=1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-import-resolver-node": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
|
||||
@ -14526,15 +14588,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"optional": true,
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
|
||||
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
@ -21723,6 +21786,14 @@
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^1.18.2 || ^2.0.0",
|
||||
"source-map": "^0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/component-compiler-utils": {
|
||||
@ -21774,6 +21845,13 @@
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
@ -24702,6 +24780,20 @@
|
||||
"semver": "^6.3.0"
|
||||
}
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-import-resolver-alias": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-alias/-/eslint-import-resolver-alias-1.1.2.tgz",
|
||||
"integrity": "sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-import-resolver-node": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
|
||||
@ -29843,10 +29935,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"optional": true
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
|
||||
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty": {
|
||||
"version": "2.0.0",
|
||||
|
@ -35,7 +35,9 @@
|
||||
"chai": "^4.3.6",
|
||||
"dotenv": "^16.4.5",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-vue": "^9.1.1",
|
||||
"eslint-plugin-vuejs-accessibility": "^1.2.0",
|
||||
"glob-parent": ">=5.1.2",
|
||||
@ -46,6 +48,7 @@
|
||||
"nyc": "^15.1.0",
|
||||
"openai": "^4.65.0",
|
||||
"plugin-error": "^2.0.1",
|
||||
"prettier": "^3.4.2",
|
||||
"sass": "~1.81.0",
|
||||
"sass-loader": "^13.0.0",
|
||||
"stylus": "^0.64.0",
|
||||
|
@ -6,7 +6,6 @@
|
||||
></v-progress-linear>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
||||
<NewTaskDialog
|
||||
v-model="newTaskDialog"
|
||||
:project-id="projectId"
|
||||
@ -17,20 +16,20 @@
|
||||
/>
|
||||
|
||||
<EditTemplateDialogue
|
||||
v-model="editDialog"
|
||||
:project-id="projectId"
|
||||
:item-app="item.app"
|
||||
:item-id="itemId"
|
||||
@save="loadData()"
|
||||
v-model="editDialog"
|
||||
:project-id="projectId"
|
||||
:item-app="item.app"
|
||||
:item-id="itemId"
|
||||
@save="loadData()"
|
||||
></EditTemplateDialogue>
|
||||
|
||||
<EditTemplateDialogue
|
||||
v-model="copyDialog"
|
||||
:project-id="projectId"
|
||||
:item-app="item.app"
|
||||
item-id="new"
|
||||
:source-item-id="itemId"
|
||||
@save="onTemplateCopied"
|
||||
v-model="copyDialog"
|
||||
:project-id="projectId"
|
||||
:item-app="item.app"
|
||||
item-id="new"
|
||||
:source-item-id="itemId"
|
||||
@save="onTemplateCopied"
|
||||
></EditTemplateDialogue>
|
||||
|
||||
<ObjectRefsDialog
|
||||
@ -52,11 +51,13 @@
|
||||
<v-toolbar-title class="breadcrumbs">
|
||||
<router-link
|
||||
class="breadcrumbs__item breadcrumbs__item--link"
|
||||
:to="viewId
|
||||
:to="
|
||||
viewId
|
||||
? `/project/${projectId}/views/${viewId}/templates/`
|
||||
: `/project/${projectId}/templates/`"
|
||||
: `/project/${projectId}/templates/`
|
||||
"
|
||||
>
|
||||
{{ $t('taskTemplates2') }}
|
||||
{{ $t("taskTemplates2") }}
|
||||
</router-link>
|
||||
<v-icon>mdi-chevron-right</v-icon>
|
||||
<span class="breadcrumbs__item">{{ item.name }}</span>
|
||||
@ -64,32 +65,24 @@
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn color="primary" depressed class="mr-3" @click="newTaskDialog = true">
|
||||
<v-btn
|
||||
color="primary"
|
||||
depressed
|
||||
class="mr-3"
|
||||
@click="newTaskDialog = true"
|
||||
>
|
||||
{{ $t(TEMPLATE_TYPE_ACTION_TITLES[item.type]) }}
|
||||
</v-btn>
|
||||
|
||||
<v-btn
|
||||
icon
|
||||
color="error"
|
||||
@click="askDelete()"
|
||||
v-if="canUpdate"
|
||||
>
|
||||
<v-btn icon color="error" @click="askDelete()" v-if="canUpdate">
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn
|
||||
icon
|
||||
@click="copyDialog = true"
|
||||
v-if="canUpdate"
|
||||
>
|
||||
<v-btn icon @click="copyDialog = true" v-if="canUpdate">
|
||||
<v-icon>mdi-content-copy</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn
|
||||
icon
|
||||
@click="editDialog = true"
|
||||
v-if="canUpdate"
|
||||
>
|
||||
<v-btn icon @click="editDialog = true" v-if="canUpdate">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
@ -100,7 +93,8 @@
|
||||
type="info"
|
||||
class="mb-0 ml-4 mr-4 mb-2"
|
||||
v-if="item.description"
|
||||
>{{ item.description }}
|
||||
>
|
||||
{{ item.description }}
|
||||
</v-alert>
|
||||
|
||||
<v-row>
|
||||
@ -112,7 +106,7 @@
|
||||
</v-list-item-icon>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('playbook') }}</v-list-item-title>
|
||||
<v-list-item-title>{{ $t("playbook") }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ item.playbook }}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
@ -126,8 +120,9 @@
|
||||
</v-list-item-icon>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('type') }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ $t(TEMPLATE_TYPE_TITLES[item.type]) }}
|
||||
<v-list-item-title>{{ $t("type") }}</v-list-item-title>
|
||||
<v-list-item-subtitle
|
||||
>{{ $t(TEMPLATE_TYPE_TITLES[item.type]) }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
@ -141,9 +136,15 @@
|
||||
</v-list-item-icon>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('inventory') }}</v-list-item-title>
|
||||
<v-list-item-title>{{ $t("inventory") }}</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{ (inventory.find((x) => x.id === item.inventory_id) || {name: '—'}).name }}
|
||||
{{
|
||||
(
|
||||
inventory.find((x) => x.id === item.inventory_id) || {
|
||||
name: "—",
|
||||
}
|
||||
).name
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
@ -156,9 +157,11 @@
|
||||
<v-icon>mdi-code-braces</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('environment') }}</v-list-item-title>
|
||||
<v-list-item-title>{{ $t("environment") }}</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{ environment.find((x) => x.id === item.environment_id).name }}
|
||||
{{
|
||||
environment.find((x) => x.id === item.environment_id).name
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
@ -171,9 +174,11 @@
|
||||
<v-icon>mdi-git</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('repository2') }}</v-list-item-title>
|
||||
<v-list-item-title>{{ $t("repository2") }}</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{ repositories.find((x) => x.id === item.repository_id).name }}
|
||||
{{
|
||||
repositories.find((x) => x.id === item.repository_id).name
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
@ -182,12 +187,17 @@
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<TaskList :template="item"/>
|
||||
<v-tabs show-arrows class="pl-4">
|
||||
<v-tab key="tasks">{{ $t("tasks") }} </v-tab>
|
||||
|
||||
<v-tab v-if="app === 'terraform' || app === 'tofu'" key="state">{{
|
||||
$t("state")
|
||||
}}</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
<TaskList :template="item" />
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import EventBus from '@/event-bus';
|
||||
@ -262,10 +272,9 @@ export default {
|
||||
return this.itemId === 'new';
|
||||
},
|
||||
isLoaded() {
|
||||
return this.item
|
||||
&& this.inventory
|
||||
&& this.environment
|
||||
&& this.repositories;
|
||||
return (
|
||||
this.item && this.inventory && this.environment && this.repositories
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
@ -291,11 +300,13 @@ export default {
|
||||
},
|
||||
|
||||
async askDelete() {
|
||||
this.itemRefs = (await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/templates/${this.itemId}/refs`,
|
||||
responseType: 'json',
|
||||
})).data;
|
||||
this.itemRefs = (
|
||||
await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/templates/${this.itemId}/refs`,
|
||||
responseType: 'json',
|
||||
})
|
||||
).data;
|
||||
|
||||
if (this.itemRefs.integrations.length > 0) {
|
||||
this.itemRefsDialog = true;
|
||||
@ -338,29 +349,37 @@ export default {
|
||||
},
|
||||
|
||||
async loadData() {
|
||||
this.item = (await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/templates/${this.itemId}`,
|
||||
responseType: 'json',
|
||||
})).data;
|
||||
this.item = (
|
||||
await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/templates/${this.itemId}`,
|
||||
responseType: 'json',
|
||||
})
|
||||
).data;
|
||||
|
||||
this.inventory = (await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/inventory`,
|
||||
responseType: 'json',
|
||||
})).data;
|
||||
this.inventory = (
|
||||
await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/inventory`,
|
||||
responseType: 'json',
|
||||
})
|
||||
).data;
|
||||
|
||||
this.environment = (await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/environment`,
|
||||
responseType: 'json',
|
||||
})).data;
|
||||
this.environment = (
|
||||
await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/environment`,
|
||||
responseType: 'json',
|
||||
})
|
||||
).data;
|
||||
|
||||
this.repositories = (await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/repositories`,
|
||||
responseType: 'json',
|
||||
})).data;
|
||||
this.repositories = (
|
||||
await axios({
|
||||
method: 'get',
|
||||
url: `/api/project/${this.projectId}/repositories`,
|
||||
responseType: 'json',
|
||||
})
|
||||
).data;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user