plugin-ui-for-kzt 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/index.js +31 -0
- package/dist/types/components/Toaster/timer.d.ts +12 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/plugins/modalPlugin.d.ts +16 -0
- package/dist/types/plugins/toasterPlugin.d.ts +26 -0
- package/dist/types/store/modal.d.ts +11 -0
- package/dist/types/types/index.d.ts +4 -0
- package/package.json +46 -0
- package/public/close-icon.svg +3 -0
- package/public/error-icon.svg +5 -0
- package/public/success-icon.svg +4 -0
- package/shims-vue.d.ts +5 -0
- package/src/components/AboutPage/AboutPage.vue +1 -0
- package/src/components/DataTable/DataTable.vue +169 -0
- package/src/components/DataTable/README.md +57 -0
- package/src/components/Modal/Modal.vue +149 -0
- package/src/components/Modal/README.md +47 -0
- package/src/components/Spinner/README.md +35 -0
- package/src/components/Spinner/Spinner.vue +59 -0
- package/src/components/Toaster/README.md +69 -0
- package/src/components/Toaster/Toaster.vue +235 -0
- package/src/components/Toaster/timer.ts +45 -0
- package/src/components/Tooltip/README.md +37 -0
- package/src/components/Tooltip/Tooltip.vue +96 -0
- package/src/components/icons/CloseIcon.vue +5 -0
- package/src/components/icons/ErrorIcon.vue +7 -0
- package/src/components/icons/InfoIcon.vue +7 -0
- package/src/components/icons/SuccessIcon.vue +6 -0
- package/src/components/icons/WarningIcon.vue +7 -0
- package/src/index.ts +27 -0
- package/src/plugins/modalPlugin.ts +81 -0
- package/src/plugins/toasterPlugin.ts +179 -0
- package/src/store/modal.ts +22 -0
- package/src/styles/index.scss +3 -0
- package/src/types/index.ts +4 -0
- package/tsconfig.json +31 -0
- package/webpack.config.js +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# plugin-ui-kzt
|
|
2
|
+
|
|
3
|
+
A custom UI plugin for Vue 3 + TypeScript projects, with Quasar integration support.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### Prerequisites
|
|
10
|
+
- Node.js version **23.x** or higher
|
|
11
|
+
|
|
12
|
+
### Install the Plugin
|
|
13
|
+
```bash
|
|
14
|
+
npm install plugin-ui-for-kzt
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quasar Project Setup
|
|
20
|
+
|
|
21
|
+
If you are using **Quasar**, follow these additional steps:
|
|
22
|
+
|
|
23
|
+
1. **Create a Boot File:**
|
|
24
|
+
- Create a new file named `plugin-ui-for-kzt.ts` inside the `boot/` folder.
|
|
25
|
+
|
|
26
|
+
2. **Register the Boot File:**
|
|
27
|
+
- In `quasar.config.js`, add `'plugin-ui-for-kzt'` to the `boot` array:
|
|
28
|
+
```js
|
|
29
|
+
boot: [
|
|
30
|
+
'plugin-ui-kzt',
|
|
31
|
+
// other boot files
|
|
32
|
+
]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
3. **Import in `client-entry.js`:**
|
|
36
|
+
- Import your boot file inside the `Promise.all` method:
|
|
37
|
+
```js
|
|
38
|
+
import('boot/plugin-ui-for-kzt')
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Publishing the Plugin to npm
|
|
44
|
+
|
|
45
|
+
Follow these steps to update and publish the plugin:
|
|
46
|
+
|
|
47
|
+
1. **Update the Version:**
|
|
48
|
+
- Before publishing, **update the `version`** field in `package.json` (according to semantic versioning).
|
|
49
|
+
|
|
50
|
+
2. **Push Changes to GitLab:**
|
|
51
|
+
- Commit and push all your changes to your GitLab repository.
|
|
52
|
+
|
|
53
|
+
3. **Login to npm:**
|
|
54
|
+
```bash
|
|
55
|
+
npm login
|
|
56
|
+
```
|
|
57
|
+
- Use the **npm credentials** stored in GitLab.
|
|
58
|
+
|
|
59
|
+
4. **Publish the Plugin:**
|
|
60
|
+
```bash
|
|
61
|
+
npm publish --access public
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
5. **Clear Cache (Recommended):**
|
|
65
|
+
```bash
|
|
66
|
+
npm cache clean --force
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
6. **Update Plugin in Your Project:**
|
|
70
|
+
```bash
|
|
71
|
+
npm install plugin-ui-for-kzt@latest --force
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
7. **Clean and Run Your Quasar Project:**
|
|
75
|
+
```bash
|
|
76
|
+
quasar clean
|
|
77
|
+
quasar dev
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
✅ Done! Now your updated plugin will be installed and ready to use!
|
|
83
|
+
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
+
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
else if(typeof define === 'function' && define.amd)
|
|
5
|
+
define([], factory);
|
|
6
|
+
else if(typeof exports === 'object')
|
|
7
|
+
exports["ModalPluginNikitas"] = factory();
|
|
8
|
+
else
|
|
9
|
+
root["ModalPluginNikitas"] = factory();
|
|
10
|
+
})(this, () => {
|
|
11
|
+
return /******/ (() => { // webpackBootstrap
|
|
12
|
+
/******/ var __webpack_modules__ = ([
|
|
13
|
+
/* 0 */
|
|
14
|
+
/***/ (() => {
|
|
15
|
+
|
|
16
|
+
throw new Error("Module build failed (from ./node_modules/ts-loader/index.js):\nError: TypeScript emitted no output for /Users/agusha/Desktop/work/kaztel/modal-plugin-nikitas/src/index.ts.\n at makeSourceMapAndFinish (/Users/agusha/Desktop/work/kaztel/modal-plugin-nikitas/node_modules/ts-loader/dist/index.js:55:18)\n at successLoader (/Users/agusha/Desktop/work/kaztel/modal-plugin-nikitas/node_modules/ts-loader/dist/index.js:42:5)\n at Object.loader (/Users/agusha/Desktop/work/kaztel/modal-plugin-nikitas/node_modules/ts-loader/dist/index.js:23:5)");
|
|
17
|
+
|
|
18
|
+
/***/ })
|
|
19
|
+
/******/ ]);
|
|
20
|
+
/************************************************************************/
|
|
21
|
+
/******/
|
|
22
|
+
/******/ // startup
|
|
23
|
+
/******/ // Load entry module and return exports
|
|
24
|
+
/******/ // This entry module doesn't tell about it's top-level declarations so it can't be inlined
|
|
25
|
+
/******/ var __webpack_exports__ = {};
|
|
26
|
+
/******/ __webpack_modules__[0]();
|
|
27
|
+
/******/
|
|
28
|
+
/******/ return __webpack_exports__;
|
|
29
|
+
/******/ })()
|
|
30
|
+
;
|
|
31
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare class Timer {
|
|
2
|
+
private timerId;
|
|
3
|
+
private start;
|
|
4
|
+
private remaining;
|
|
5
|
+
private callback;
|
|
6
|
+
constructor(callback: () => void, delay: number);
|
|
7
|
+
pause(): void;
|
|
8
|
+
resume(): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
reset(delay: number): void;
|
|
11
|
+
}
|
|
12
|
+
export default Timer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Modal from "./components/Modal/Modal.vue";
|
|
2
|
+
import DataTable from "./components/DataTable/DataTable.vue";
|
|
3
|
+
import Tooltip from "./components/Tooltip/Tooltip.vue";
|
|
4
|
+
import Spinner from "./components/Spinner/Spinner.vue";
|
|
5
|
+
import { useModal } from "./plugins/modalPlugin";
|
|
6
|
+
import { useToast } from "./plugins/toasterPlugin";
|
|
7
|
+
declare const _default: {
|
|
8
|
+
install(app: any): void;
|
|
9
|
+
};
|
|
10
|
+
export default _default;
|
|
11
|
+
export { Modal, DataTable, Tooltip, Spinner, useModal, useToast };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
install(app: any): void;
|
|
3
|
+
};
|
|
4
|
+
export default _default;
|
|
5
|
+
export declare function useModal(): {
|
|
6
|
+
open: (name: string, options?: Record<string, any>) => void;
|
|
7
|
+
close: (id: number) => void;
|
|
8
|
+
} | undefined;
|
|
9
|
+
declare module "@vue/runtime-core" {
|
|
10
|
+
interface ComponentCustomProperties {
|
|
11
|
+
$modal: {
|
|
12
|
+
open: (name: string, options?: Record<string, any>) => void;
|
|
13
|
+
close: (id: number) => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface ToastOptions {
|
|
2
|
+
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
3
|
+
duration?: number;
|
|
4
|
+
dismissible?: boolean;
|
|
5
|
+
pauseOnHover?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const _default: {
|
|
8
|
+
install(app: any): void;
|
|
9
|
+
};
|
|
10
|
+
export default _default;
|
|
11
|
+
export declare function useToast(): {
|
|
12
|
+
success: (message: string, options?: ToastOptions) => void;
|
|
13
|
+
error: (message: string, options?: ToastOptions) => void;
|
|
14
|
+
info: (message: string, options?: ToastOptions) => void;
|
|
15
|
+
warning: (message: string, options?: ToastOptions) => void;
|
|
16
|
+
} | undefined;
|
|
17
|
+
declare module "@vue/runtime-core" {
|
|
18
|
+
interface ComponentCustomProperties {
|
|
19
|
+
$toast: {
|
|
20
|
+
success: (message: string, options?: ToastOptions) => void;
|
|
21
|
+
error: (message: string, options?: ToastOptions) => void;
|
|
22
|
+
info: (message: string, options?: ToastOptions) => void;
|
|
23
|
+
warning: (message: string, options?: ToastOptions) => void;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IModalState } from "../types";
|
|
2
|
+
export declare const useModalStore: import("pinia").StoreDefinition<"modal", {
|
|
3
|
+
modals: Array<{
|
|
4
|
+
id: number;
|
|
5
|
+
name: string;
|
|
6
|
+
options: IModalState;
|
|
7
|
+
}>;
|
|
8
|
+
}, {}, {
|
|
9
|
+
openModal(name: string, options: IModalState): void;
|
|
10
|
+
closeModal(id: number): void;
|
|
11
|
+
}>;
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "plugin-ui-for-kzt",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "plugin-ui for kazaktelekom",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/types/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "webpack --config webpack.config.js",
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://git.itte.kz/development-center/components/plugin-ui.git"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"vue",
|
|
17
|
+
"vue3",
|
|
18
|
+
"plugin",
|
|
19
|
+
"modal",
|
|
20
|
+
"plugin-ui"
|
|
21
|
+
],
|
|
22
|
+
"author": "nikitos.nik.523@gmail.com",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://git.itte.kz/development-center/components/plugin-ui.git/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://git.itte.kz/development-center/components/plugin-ui.git#readme",
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"vue": "^3.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"css-loader": "^7.1.2",
|
|
33
|
+
"sass": "^1.83.4",
|
|
34
|
+
"sass-loader": "^12.6.0",
|
|
35
|
+
"ts-loader": "^9.0.0",
|
|
36
|
+
"vue-loader": "^16.8.3",
|
|
37
|
+
"vue-style-loader": "^4.1.3",
|
|
38
|
+
"vue-template-compiler": "^2.7.16",
|
|
39
|
+
"webpack": "^5.97.1",
|
|
40
|
+
"webpack-cli": "^4.10.0"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"pinia": "^2.3.1",
|
|
44
|
+
"vue": "^3.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.7592 1.51746C16.0803 1.17049 16.0803 0.607198 15.7592 0.260228C15.3311 -0.0867426 14.796 -0.0867426 14.4749 0.260228L7.94649 6.74237L1.52508 0.260228C1.09699 -0.0867426 0.561873 -0.0867426 0.240803 0.260228C-0.0802676 0.607198 -0.0802676 1.17049 0.240803 1.51746L6.76923 7.9996L0.240803 14.4828C-0.0802676 14.8298 -0.0802676 15.392 0.240803 15.739C0.561873 16.087 1.09699 16.087 1.52508 15.739L7.94649 9.25683L14.4749 15.739C14.796 16.087 15.3311 16.087 15.7592 15.739C16.0803 15.392 16.0803 14.8298 15.7592 14.4828L9.23077 7.9996L15.7592 1.51746Z" fill="white"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="45" height="40" viewBox="0 0 45 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M42.8186 36.4103L23.3834 2.5641C22.9908 1.88034 22.0092 1.88034 21.6166 2.5641L2.1814 36.4103C1.78877 37.094 2.27955 37.9487 3.06481 37.9487H41.9352C42.7205 37.9487 43.2112 37.094 42.8186 36.4103ZM25.1503 1.53846C23.9724 -0.512819 21.0276 -0.512822 19.8498 1.53846L0.414562 35.3846C-0.763329 37.4359 0.709031 40 3.06481 40H41.9352C44.291 40 45.7633 37.4359 44.5854 35.3846L25.1503 1.53846Z" fill="white"/>
|
|
3
|
+
<rect x="21.6213" y="10.2565" width="2.04017" height="17.4359" rx="1.02008" fill="white"/>
|
|
4
|
+
<ellipse cx="22.712" cy="32.3076" rx="1.53012" ry="1.53846" fill="white"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<circle cx="24" cy="24" r="22.5" stroke="white" stroke-width="3"/>
|
|
3
|
+
<path d="M35.04 14.4L19.86 33.6L12.96 24.8728" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
package/shims-vue.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template> <div>je;;p</div></template>
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="table-container">
|
|
3
|
+
<div class="search-container">
|
|
4
|
+
<input
|
|
5
|
+
type="text"
|
|
6
|
+
placeholder="Поиск..."
|
|
7
|
+
:value="searchQuery"
|
|
8
|
+
@input="handleSearchInput"
|
|
9
|
+
/>
|
|
10
|
+
<p v-if="!searchExists">Ничего не найдено</p>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<table v-if="searchExists">
|
|
14
|
+
<thead>
|
|
15
|
+
<tr>
|
|
16
|
+
<th v-for="column in props.columns" :key="column.key">
|
|
17
|
+
{{ column.label }}
|
|
18
|
+
</th>
|
|
19
|
+
</tr>
|
|
20
|
+
</thead>
|
|
21
|
+
<tbody>
|
|
22
|
+
<tr v-for="(row, rowIndex) in paginatedRows" :key="rowIndex">
|
|
23
|
+
<td v-for="column in props.columns" :key="column.key">
|
|
24
|
+
{{ row[column.key] }}
|
|
25
|
+
</td>
|
|
26
|
+
</tr>
|
|
27
|
+
</tbody>
|
|
28
|
+
</table>
|
|
29
|
+
|
|
30
|
+
<div v-if="searchExists" class="pagination">
|
|
31
|
+
<button @click="goToPreviousPage" :disabled="currentPage === 1">
|
|
32
|
+
Предыдущая
|
|
33
|
+
</button>
|
|
34
|
+
<span>Страница {{ currentPage }} из {{ totalPages }}</span>
|
|
35
|
+
<button @click="goToNextPage" :disabled="currentPage === totalPages">
|
|
36
|
+
Следующая
|
|
37
|
+
</button>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script setup lang="ts">
|
|
43
|
+
import {ref, computed} from 'vue';
|
|
44
|
+
|
|
45
|
+
interface TableColumn {
|
|
46
|
+
key: string;
|
|
47
|
+
label: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface TableProps {
|
|
51
|
+
columns: TableColumn[];
|
|
52
|
+
rows: Record<string, any>[];
|
|
53
|
+
pageSize?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const props = defineProps<TableProps>();
|
|
57
|
+
|
|
58
|
+
// states
|
|
59
|
+
const searchQuery = ref<string>('');
|
|
60
|
+
const currentPage = ref<number>(1);
|
|
61
|
+
const rowsPerPage = ref<number>(props.pageSize ?? 5);
|
|
62
|
+
|
|
63
|
+
// computed properties
|
|
64
|
+
const filteredRows = computed(() => {
|
|
65
|
+
if (!searchQuery.value) {
|
|
66
|
+
return props.rows;
|
|
67
|
+
}
|
|
68
|
+
const query = searchQuery.value.toLowerCase();
|
|
69
|
+
return props.rows.filter((row: string | any) =>
|
|
70
|
+
Object.values(row).some((val) =>
|
|
71
|
+
String(val).toLowerCase().includes(query)
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
const searchExists = computed(() => filteredRows.value.length > 0);
|
|
76
|
+
const totalPages = computed(() =>
|
|
77
|
+
Math.ceil(filteredRows.value.length / rowsPerPage.value)
|
|
78
|
+
);
|
|
79
|
+
const startIndex = computed(() => (currentPage.value - 1) * rowsPerPage.value);
|
|
80
|
+
const endIndex = computed(() => currentPage.value * rowsPerPage.value);
|
|
81
|
+
const paginatedRows = computed(() =>
|
|
82
|
+
filteredRows.value.slice(startIndex.value, endIndex.value)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// functions
|
|
86
|
+
const goToPreviousPage = (): void => {
|
|
87
|
+
if (currentPage.value > 1) {
|
|
88
|
+
currentPage.value--;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const goToNextPage = (): void => {
|
|
92
|
+
if (currentPage.value < totalPages.value) {
|
|
93
|
+
currentPage.value++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const handleSearchInput = (event: Event): void => {
|
|
97
|
+
searchQuery.value = (event.target as HTMLInputElement).value;
|
|
98
|
+
currentPage.value = 1;
|
|
99
|
+
}
|
|
100
|
+
</script>
|
|
101
|
+
|
|
102
|
+
<style scoped lang="scss">
|
|
103
|
+
.table-container {
|
|
104
|
+
max-width: 100%;
|
|
105
|
+
overflow-x: auto;
|
|
106
|
+
padding: 1rem;
|
|
107
|
+
|
|
108
|
+
.search-container {
|
|
109
|
+
margin-bottom: 1rem;
|
|
110
|
+
|
|
111
|
+
input {
|
|
112
|
+
padding: 0.5rem;
|
|
113
|
+
border: 1px solid #ccc;
|
|
114
|
+
border-radius: 4px;
|
|
115
|
+
|
|
116
|
+
&:focus {
|
|
117
|
+
outline: none;
|
|
118
|
+
border-color: #90caf9;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
table {
|
|
124
|
+
width: 100%;
|
|
125
|
+
border-collapse: collapse;
|
|
126
|
+
margin-bottom: 1rem;
|
|
127
|
+
|
|
128
|
+
thead {
|
|
129
|
+
background-color: #e3f2fd;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
th, td {
|
|
133
|
+
padding: 0.75rem 1rem;
|
|
134
|
+
border: 1px solid #ccc;
|
|
135
|
+
text-align: left;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.pagination {
|
|
140
|
+
display: flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
justify-content: flex-end;
|
|
143
|
+
|
|
144
|
+
button {
|
|
145
|
+
background-color: #90caf9;
|
|
146
|
+
color: #fff;
|
|
147
|
+
border: none;
|
|
148
|
+
padding: 0.5rem 1rem;
|
|
149
|
+
margin: 0 0.25rem;
|
|
150
|
+
border-radius: 4px;
|
|
151
|
+
cursor: pointer;
|
|
152
|
+
transition: background-color 0.2s ease;
|
|
153
|
+
|
|
154
|
+
&:hover:not(:disabled) {
|
|
155
|
+
background-color: #64b5f6;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&:disabled {
|
|
159
|
+
background-color: #ccc;
|
|
160
|
+
cursor: not-allowed;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
span {
|
|
165
|
+
margin: 0 0.5rem;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Документация компонента DataTable
|
|
2
|
+
|
|
3
|
+
## Обзор
|
|
4
|
+
Компонент `DataTable` предназначен для отображения табличных данных с поддержкой поиска и постраничной навигации. Он позволяет передавать список колонок и строк, а также управлять размером страницы.
|
|
5
|
+
|
|
6
|
+
## Свойства (Props)
|
|
7
|
+
|
|
8
|
+
- `columns` (массив объектов) – список колонок, каждая из которых содержит ключ `key` (для доступа к данным) и `label` (отображаемое название).
|
|
9
|
+
- `rows` (массив объектов) – массив данных, где каждый объект представляет строку таблицы.
|
|
10
|
+
- `pageSize` (число, необязательно) – количество строк, отображаемых на одной странице. По умолчанию `5`.
|
|
11
|
+
|
|
12
|
+
## Вычисляемые свойства (Computed)
|
|
13
|
+
|
|
14
|
+
- `filteredRows` – список строк, отфильтрованный по поисковому запросу.
|
|
15
|
+
- `searchExists` – определяет, есть ли в таблице совпадающие результаты поиска.
|
|
16
|
+
- `totalPages` – вычисляет общее количество страниц на основе размера страницы и количества строк.
|
|
17
|
+
- `startIndex` – индекс начала текущей страницы.
|
|
18
|
+
- `endIndex` – индекс конца текущей страницы.
|
|
19
|
+
- `paginatedRows` – список строк, отображаемых на текущей странице.
|
|
20
|
+
|
|
21
|
+
## Методы
|
|
22
|
+
|
|
23
|
+
### `goToPreviousPage()`
|
|
24
|
+
Переходит на предыдущую страницу, если это возможно.
|
|
25
|
+
|
|
26
|
+
### `goToNextPage()`
|
|
27
|
+
Переходит на следующую страницу, если это возможно.
|
|
28
|
+
|
|
29
|
+
### `handleSearchInput(event: Event)`
|
|
30
|
+
Обновляет поисковый запрос при вводе текста в поле поиска и сбрасывает текущую страницу на первую.
|
|
31
|
+
|
|
32
|
+
## Использование
|
|
33
|
+
|
|
34
|
+
```vue
|
|
35
|
+
<DataTable
|
|
36
|
+
:columns="[
|
|
37
|
+
{ key: 'name', label: 'Имя' },
|
|
38
|
+
{ key: 'age', label: 'Возраст' },
|
|
39
|
+
{ key: 'email', label: 'Email' }
|
|
40
|
+
]"
|
|
41
|
+
:rows="[
|
|
42
|
+
{ name: 'Иван', age: 25, email: 'ivan@example.com' },
|
|
43
|
+
{ name: 'Мария', age: 30, email: 'maria@example.com' },
|
|
44
|
+
{ name: 'Алексей', age: 28, email: 'alex@example.com' }
|
|
45
|
+
]"
|
|
46
|
+
:pageSize="2"
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Функциональность
|
|
51
|
+
|
|
52
|
+
- Поддержка поиска по всем значениям строк.
|
|
53
|
+
- Автоматическая фильтрация результатов.
|
|
54
|
+
- Пагинация с кнопками "Предыдущая" и "Следующая".
|
|
55
|
+
- Отображение сообщения, если совпадений не найдено.
|
|
56
|
+
|
|
57
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="modal-container" @click.stop>
|
|
3
|
+
<div
|
|
4
|
+
class="modal-container-header"
|
|
5
|
+
:class="{
|
|
6
|
+
'modal-container-header-show-all': showMore,
|
|
7
|
+
[getTypeModal.nameClass]: getTypeModal.nameClass !== '',
|
|
8
|
+
}"
|
|
9
|
+
>
|
|
10
|
+
<div class="modal-container-header-title">
|
|
11
|
+
<component :is="getTypeModal.img" />
|
|
12
|
+
<div>{{ options.title }}</div>
|
|
13
|
+
</div>
|
|
14
|
+
<div
|
|
15
|
+
class="modal-container-header-show-more"
|
|
16
|
+
@click="showMore = !showMore"
|
|
17
|
+
>
|
|
18
|
+
{{ showMore ? "Скрыть" : "Смотреть больше" }}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<CloseIcon class="modal-button-close" @click="onClose" />
|
|
22
|
+
<div v-if="showMore" class="modal-container-subtitle">
|
|
23
|
+
Описание: <br />
|
|
24
|
+
{{ options.message }}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
import { ref, computed } from "vue";
|
|
31
|
+
import CloseIcon from "../icons/CloseIcon.vue";
|
|
32
|
+
import ErrorIcon from "../icons/ErrorIcon.vue";
|
|
33
|
+
import SuccessIcon from "../icons/SuccessIcon.vue";
|
|
34
|
+
import WarningIcon from "../icons/WarningIcon.vue";
|
|
35
|
+
import InfoIcon from "../icons/InfoIcon.vue";
|
|
36
|
+
|
|
37
|
+
interface IProps {
|
|
38
|
+
options: {
|
|
39
|
+
title: string;
|
|
40
|
+
message: string;
|
|
41
|
+
};
|
|
42
|
+
name: string;
|
|
43
|
+
onClose: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const props = defineProps<IProps>();
|
|
47
|
+
const showMore = ref<boolean>(false);
|
|
48
|
+
|
|
49
|
+
const getTypeModal = computed<{ img: any; nameClass: string }>(() => {
|
|
50
|
+
switch (props.name) {
|
|
51
|
+
case "error":
|
|
52
|
+
return { img: ErrorIcon, nameClass: "error" };
|
|
53
|
+
case "success":
|
|
54
|
+
return { img: SuccessIcon, nameClass: "success" };
|
|
55
|
+
case "warning":
|
|
56
|
+
return { img: WarningIcon, nameClass: "warning" };
|
|
57
|
+
case "info":
|
|
58
|
+
return { img: InfoIcon, nameClass: "info" };
|
|
59
|
+
default:
|
|
60
|
+
return {
|
|
61
|
+
img: SuccessIcon,
|
|
62
|
+
nameClass: "",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<style lang="scss">
|
|
69
|
+
.modal {
|
|
70
|
+
position: fixed;
|
|
71
|
+
top: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
width: 100%;
|
|
74
|
+
height: 100%;
|
|
75
|
+
display: flex;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
align-items: center;
|
|
78
|
+
background: rgba(0, 0, 0, 0.2);
|
|
79
|
+
z-index: 9999;
|
|
80
|
+
|
|
81
|
+
&-button-close {
|
|
82
|
+
width: 12px;
|
|
83
|
+
height: 12px;
|
|
84
|
+
position: absolute;
|
|
85
|
+
top: 20px;
|
|
86
|
+
right: 20px;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&-container {
|
|
91
|
+
position: relative;
|
|
92
|
+
font-family: "Roboto Condensed", serif;
|
|
93
|
+
font-optical-sizing: auto;
|
|
94
|
+
|
|
95
|
+
background: white;
|
|
96
|
+
border-radius: 16px;
|
|
97
|
+
max-width: 540px;
|
|
98
|
+
width: 100%;
|
|
99
|
+
|
|
100
|
+
&-header {
|
|
101
|
+
padding: 20px;
|
|
102
|
+
border-radius: 12px;
|
|
103
|
+
font-size: 20px;
|
|
104
|
+
font-weight: 400;
|
|
105
|
+
line-height: 24px;
|
|
106
|
+
&-show-all {
|
|
107
|
+
border-radius: 12px 12px 0 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&-title {
|
|
111
|
+
color: white;
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: start;
|
|
114
|
+
gap: 20px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
&-show-more {
|
|
118
|
+
color: #f5c9c3;
|
|
119
|
+
text-align: right;
|
|
120
|
+
font-size: 16px;
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&-subtitle {
|
|
126
|
+
padding: 20px;
|
|
127
|
+
font-size: 18px;
|
|
128
|
+
font-weight: 400;
|
|
129
|
+
line-height: 24px;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.error {
|
|
135
|
+
background: #ee5542;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.success {
|
|
139
|
+
background: #15b853;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.warning {
|
|
143
|
+
background: #f4a900;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.warning {
|
|
147
|
+
background: #0085cf;
|
|
148
|
+
}
|
|
149
|
+
</style>
|