adminforth 1.1.74 → 1.1.75

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.
Files changed (115) hide show
  1. package/auth.ts +14 -0
  2. package/dataConnectors/postgres.ts +1 -1
  3. package/dist/auth.js +7 -0
  4. package/dist/index.js +117 -65
  5. package/dist/modules/codeInjector.js +29 -15
  6. package/dist/plugins/AuditLogPlugin/index.js +2 -17
  7. package/dist/plugins/S3UploadPlugin/custom/s3uploader.vue +120 -0
  8. package/dist/plugins/S3UploadPlugin/index.js +103 -0
  9. package/dist/plugins/S3UploadPlugin/package-lock.json +431 -0
  10. package/dist/plugins/S3UploadPlugin/package.json +15 -0
  11. package/dist/plugins/TwoFactorsAuthPlugin/custom/TwoFactorsConfirmation.vue +152 -0
  12. package/dist/plugins/TwoFactorsAuthPlugin/custom/TwoFactorsSetup.vue +188 -0
  13. package/dist/plugins/TwoFactorsAuthPlugin/index.js +150 -0
  14. package/dist/plugins/TwoFactorsAuthPlugin/types.js +1 -0
  15. package/dist/spa/index.html +1 -1
  16. package/dist/spa/package-lock.json +111 -0
  17. package/dist/spa/package.json +1 -0
  18. package/dist/spa/src/App.vue +178 -133
  19. package/dist/spa/src/components/MenuLink.vue +3 -3
  20. package/dist/spa/src/components/ResourceForm.vue +96 -96
  21. package/dist/spa/src/components/ResourceListTable.vue +69 -84
  22. package/dist/spa/src/components/ValueRenderer.vue +2 -3
  23. package/dist/spa/src/composables/useStores.ts +24 -11
  24. package/dist/spa/src/main.ts +1 -1
  25. package/dist/spa/src/router/index.ts +0 -1
  26. package/dist/spa/src/utils.ts +1 -1
  27. package/dist/spa/src/views/CreateView.vue +1 -9
  28. package/dist/spa/src/views/EditView.vue +1 -9
  29. package/dist/spa/src/views/ListView.vue +12 -3
  30. package/dist/spa/src/views/LoginView.vue +6 -1
  31. package/dist/spa/src/views/ResourceParent.vue +1 -2
  32. package/dist/spa/src/views/ShowView.vue +6 -14
  33. package/dist/spa/tailwind.config.js +3 -1
  34. package/index.ts +94 -35
  35. package/modules/codeInjector.ts +38 -27
  36. package/package.json +2 -1
  37. package/plugins/AuditLogPlugin/index.ts +4 -20
  38. package/plugins/S3UploadPlugin/custom/s3uploader.vue +120 -0
  39. package/plugins/S3UploadPlugin/index.ts +112 -0
  40. package/plugins/S3UploadPlugin/package-lock.json +431 -0
  41. package/plugins/S3UploadPlugin/package.json +15 -0
  42. package/plugins/S3UploadPlugin/types.ts +76 -0
  43. package/plugins/TwoFactorsAuthPlugin/custom/TwoFactorsConfirmation.vue +152 -0
  44. package/plugins/TwoFactorsAuthPlugin/custom/TwoFactorsOtp.vue +0 -0
  45. package/plugins/TwoFactorsAuthPlugin/custom/TwoFactorsSetup.vue +188 -0
  46. package/plugins/TwoFactorsAuthPlugin/index.ts +150 -0
  47. package/plugins/TwoFactorsAuthPlugin/types.ts +10 -0
  48. package/servers/express.ts +1 -0
  49. package/spa/src/App.vue +154 -121
  50. package/spa/src/components/ResourceForm.vue +91 -91
  51. package/spa/src/router/index.ts +0 -1
  52. package/spa/src/utils.ts +1 -1
  53. package/spa/src/views/CreateView.vue +0 -1
  54. package/spa/src/views/LoginView.vue +4 -1
  55. package/types/AdminForthConfig.ts +24 -3
  56. package/dist/plugins/AuditLog/index.js +0 -13
  57. package/dist/spa/spa/.eslintrc.cjs +0 -14
  58. package/dist/spa/spa/.vscode/extensions.json +0 -6
  59. package/dist/spa/spa/README.md +0 -39
  60. package/dist/spa/spa/env.d.ts +0 -1
  61. package/dist/spa/spa/index.html +0 -23
  62. package/dist/spa/spa/package-lock.json +0 -4470
  63. package/dist/spa/spa/package.json +0 -48
  64. package/dist/spa/spa/postcss.config.js +0 -6
  65. package/dist/spa/spa/public/assets/favicon.png +0 -0
  66. package/dist/spa/spa/src/App.vue +0 -283
  67. package/dist/spa/spa/src/assets/logo.svg +0 -19
  68. package/dist/spa/spa/src/components/AcceptModal.vue +0 -45
  69. package/dist/spa/spa/src/components/Breadcrumbs.vue +0 -40
  70. package/dist/spa/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  71. package/dist/spa/spa/src/components/CustomDatePicker.vue +0 -174
  72. package/dist/spa/spa/src/components/CustomDateRangePicker.vue +0 -218
  73. package/dist/spa/spa/src/components/CustomRangePicker.vue +0 -148
  74. package/dist/spa/spa/src/components/Dropdown.vue +0 -168
  75. package/dist/spa/spa/src/components/Filters.vue +0 -211
  76. package/dist/spa/spa/src/components/HelloWorld.vue +0 -17
  77. package/dist/spa/spa/src/components/MenuLink.vue +0 -24
  78. package/dist/spa/spa/src/components/ResourceForm.vue +0 -265
  79. package/dist/spa/spa/src/components/ResourceListTable.vue +0 -404
  80. package/dist/spa/spa/src/components/SingleSkeletLoader.vue +0 -13
  81. package/dist/spa/spa/src/components/Toast.vue +0 -66
  82. package/dist/spa/spa/src/components/ValueRenderer.vue +0 -59
  83. package/dist/spa/spa/src/components/icons/IconCalendar.vue +0 -5
  84. package/dist/spa/spa/src/components/icons/IconCommunity.vue +0 -7
  85. package/dist/spa/spa/src/components/icons/IconDocumentation.vue +0 -7
  86. package/dist/spa/spa/src/components/icons/IconEcosystem.vue +0 -7
  87. package/dist/spa/spa/src/components/icons/IconSupport.vue +0 -7
  88. package/dist/spa/spa/src/components/icons/IconTime.vue +0 -5
  89. package/dist/spa/spa/src/components/icons/IconTooling.vue +0 -19
  90. package/dist/spa/spa/src/composables/useFrontendApi.ts +0 -26
  91. package/dist/spa/spa/src/composables/useStores.ts +0 -126
  92. package/dist/spa/spa/src/index.scss +0 -26
  93. package/dist/spa/spa/src/main.ts +0 -18
  94. package/dist/spa/spa/src/router/index.ts +0 -64
  95. package/dist/spa/spa/src/spa_types/core.ts +0 -51
  96. package/dist/spa/spa/src/stores/core.ts +0 -144
  97. package/dist/spa/spa/src/stores/filters.ts +0 -22
  98. package/dist/spa/spa/src/stores/modal.ts +0 -48
  99. package/dist/spa/spa/src/stores/toast.ts +0 -15
  100. package/dist/spa/spa/src/stores/user.ts +0 -54
  101. package/dist/spa/spa/src/utils.ts +0 -101
  102. package/dist/spa/spa/src/views/CreateView.vue +0 -156
  103. package/dist/spa/spa/src/views/EditView.vue +0 -157
  104. package/dist/spa/spa/src/views/ListView.vue +0 -266
  105. package/dist/spa/spa/src/views/LoginView.vue +0 -136
  106. package/dist/spa/spa/src/views/ResourceParent.vue +0 -17
  107. package/dist/spa/spa/src/views/ShowView.vue +0 -180
  108. package/dist/spa/spa/tailwind.config.js +0 -17
  109. package/dist/spa/spa/tsconfig.app.json +0 -14
  110. package/dist/spa/spa/tsconfig.json +0 -11
  111. package/dist/spa/spa/tsconfig.node.json +0 -19
  112. package/dist/spa/spa/vite.config.ts +0 -49
  113. /package/dist/plugins/{AuditLog → S3UploadPlugin}/types.js +0 -0
  114. /package/dist/{spa/spa/src/assets/base.css → plugins/TwoFactorsAuthPlugin/custom/TwoFactorsOtp.vue} +0 -0
  115. /package/dist/spa/{spa/src → src}/components/SkeleteLoader.vue +0 -0
@@ -1,126 +0,0 @@
1
- import type { FrontendAPIInterface, ConfirmParams, AlertParams, } from '../types/FrontendAPI';
2
- import type { AdminForthFilterOperators } from '@/types/AdminForthConfig';
3
- import { useToastStore } from '../stores/toast';
4
- import { useModalStore } from '../stores/modal';
5
- import { useCoreStore } from '@/stores/core';
6
- import { useFiltersStore } from '@/stores/filters';
7
- import router from '@/router'
8
- import type { AdminForthResourceColumn } from '@/types/AdminForthConfig';
9
-
10
- type FilterParams = {
11
- /**
12
- * Field of resource to filter
13
- */
14
- field: string;
15
- /**
16
- * Operator of filter
17
- */
18
- operator: AdminForthFilterOperators;
19
- /**
20
- * Value of filter
21
- */
22
- value: string | number | boolean ;
23
- }
24
-
25
- declare global {
26
- interface Window {
27
- adminforth: {
28
- confirm: (params: ConfirmParams) => Promise<void>;
29
- alert: (params: AlertParams) => void;
30
- setListFilter: (filter: any) => void;
31
- updateListFilter: (filter: any) => void;
32
- clearListFilters: () => void;
33
- };
34
- }
35
- }
36
-
37
- export class FrontendAPI implements FrontendAPIInterface {
38
- private toastStore:any
39
- private modalStore:any
40
- private filtersStore:any
41
- private coreStore:any
42
- init() {
43
- if (window.adminforth) {
44
- throw new Error('adminforth already initialized');
45
- }
46
- this.toastStore = useToastStore();
47
- this.modalStore = useModalStore();
48
- console.log(this.toastStore, this.modalStore,'init of adminforth frontend api')
49
- window.adminforth = {
50
- confirm: this.confirm.bind(this),
51
- alert: this.alert.bind(this),
52
- setListFilter: this.setListFilter.bind(this),
53
- updateListFilter: this.updateListFilter.bind(this),
54
- clearListFilters: this.clearListFilters.bind(this),
55
- }
56
- }
57
-
58
- confirm(params: ConfirmParams): Promise<void> {
59
- return new Promise((resolve, reject) => {
60
- this.modalStore.setModalContent({ content: params.message, acceptText: params.yes, cancelText: params.no })
61
- this.modalStore.onAcceptFunction = resolve
62
- this.modalStore.onCancelFunction = reject
63
- this.modalStore.togleModal()
64
- })
65
- }
66
-
67
- alert(params: AlertParams): void {
68
- this.toastStore.addToast({
69
- message: params.message,
70
- variant: params.variant,
71
- timeout: params.timeout
72
- })
73
- }
74
-
75
- listFilterValidation(filter: FilterParams): boolean {
76
- if(router.currentRoute.value.meta.type !== 'list'){
77
- throw new Error(`Cannot use ${this.setListFilter.name} filter on a list page`)
78
- } else {
79
- if(!this.coreStore) this.coreStore = useCoreStore()
80
- console.log(this.coreStore.resourceColumnsWithFilters,'core store')
81
- const filterField = this.coreStore.resourceColumnsWithFilters.find((col: AdminForthResourceColumn) => col.name === filter.field)
82
- if(!filterField){
83
- throw new Error(`Field ${filter.field} is not available for filtering`)
84
- }
85
-
86
- }
87
- return true
88
- }
89
-
90
- setListFilter(filter: FilterParams): void {
91
- if(this.listFilterValidation(filter)){
92
- this.filtersStore = useFiltersStore()
93
- if(this.filtersStore.filters.some((f) => {return f.field === filter.field && f.operator === filter.operator})){
94
- throw new Error(`Filter ${filter.field} with operator ${filter.operator} already exists`)
95
- } else {
96
- this.filtersStore.setFilter(filter)
97
- }
98
- }
99
- }
100
-
101
- clearListFilters(): void {
102
- this.filtersStore = useFiltersStore()
103
- this.filtersStore.clearFilters()
104
- }
105
-
106
- updateListFilter(filter: FilterParams): void {
107
- if(this.listFilterValidation(filter)){
108
- this.filtersStore = useFiltersStore()
109
- const index = this.filtersStore.filters.findIndex((f: FilterParams) => f.field === filter.field)
110
- if(index === -1) {
111
- this.filtersStore.setFilter(filter)
112
- } else {
113
- const filters = [...this.filtersStore.filters];
114
- if (filter.value === undefined) {
115
- filters.splice(index, 1);
116
- } else {
117
- filters[index] = filter;
118
- }
119
- this.filtersStore.setFilters(filters);
120
- }
121
- }
122
- }
123
-
124
-
125
-
126
- }
@@ -1,26 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
-
6
- // @layer base {
7
- // /* width */
8
- // ::-webkit-scrollbar {
9
- // @apply w-2 p-2
10
- // }
11
-
12
- // /* Track */
13
- // ::-webkit-scrollbar-track {
14
- // @apply bg-inherit
15
- // }
16
-
17
- // /* Handle */
18
- // ::-webkit-scrollbar-thumb {
19
- // @apply bg-gray-200 dark:bg-gray-600 rounded-xl
20
- // }
21
-
22
- // /* Handle on hover */
23
- // ::-webkit-scrollbar-thumb:hover {
24
- // @apply bg-gray-700
25
- // }
26
- // }
@@ -1,18 +0,0 @@
1
- import { createApp } from 'vue'
2
- import { createPinia } from 'pinia'
3
- /* IMPORTANT:ADMINFORTH IMPORTS */
4
-
5
-
6
- import App from './App.vue'
7
- import router from './router'
8
-
9
- export const app = createApp(App)
10
- /* IMPORTANT:ADMINFORTH COMPONENT REGISTRATIONS */
11
-
12
-
13
- app.use(createPinia())
14
- app.use(router)
15
-
16
- /* IMPORTANT:ADMINFORTH CUSTOM USES */
17
-
18
- app.mount('#app')
@@ -1,64 +0,0 @@
1
- import { createRouter, createWebHistory } from 'vue-router'
2
- import ResourceParent from '@/views/ResourceParent.vue'
3
- import { useUserStore } from '@/stores/user'
4
- /* IMPORTANT:ADMINFORTH ROUTES IMPORTS */
5
-
6
- const router = createRouter({
7
- history: createWebHistory(import.meta.env.BASE_URL),
8
- routes: [
9
- {
10
- path: '/login',
11
- name: 'login',
12
- component: () => import('@/views/LoginView.vue'),
13
- meta: { title: 'login' },
14
- beforeEnter: async (to, from, next) => {
15
- const userStore = useUserStore()
16
- if(localStorage.getItem('isAuthorized') === 'true'){
17
- next({name: 'home'})
18
- } else {
19
- next()
20
- }
21
- }
22
- },
23
- {
24
- path: '/resource/:resourceId',
25
- component: ResourceParent,
26
- name: 'resource',
27
- children: [
28
- {
29
- path: '',
30
- component: () => import('@/views/ListView.vue'),
31
- name: 'resource-list',
32
- meta: { title: 'list',type: 'list' }
33
- },
34
- {
35
- path: 'show/:primaryKey',
36
- component: () => import('@/views/ShowView.vue'),
37
- name: 'resource-show',
38
- meta: { title: 'show', type: 'show'}
39
-
40
- },
41
- {
42
- path: 'edit/:primaryKey',
43
- component: () => import('@/views/EditView.vue'),
44
- name: 'resource-edit',
45
- meta: { title: 'edit', type: 'edit'}
46
- },
47
- {
48
- path: 'create',
49
- component: () => import('@/views/CreateView.vue'),
50
- name: 'resource-create',
51
- meta: { title: 'create', type: 'create'}
52
-
53
- },
54
- ]
55
- },
56
- /* IMPORTANT:ADMINFORTH ROUTES */
57
- ]
58
- })
59
-
60
-
61
-
62
-
63
-
64
- export default router
@@ -1,51 +0,0 @@
1
- import type { AdminForthResource, AdminForthResourceColumn } from '../types/AdminForthConfig';
2
-
3
- export type resourceById = {
4
- [key: string]: AdminForthResource;
5
- }
6
-
7
- export type Menu = {
8
- label: string,
9
- icon: string,
10
- resourceId: string,
11
- children?: Array<Menu>,
12
- }
13
-
14
- export type Record = {
15
- [key: string]: any;
16
- }
17
-
18
- export type ResourceColumns = {
19
- [key: string]: Array<AdminForthResourceColumn>;
20
- }
21
-
22
- export type CoreConfig = {
23
- brandName: string,
24
- brandLogo: string,
25
- title: string,
26
- datesFormat: string,
27
- usernameField: string,
28
- usernameFieldName?: string,
29
- deleteConfirmation?: boolean,
30
- auth?: {
31
- resourceId: string,
32
- usernameField: string,
33
- passwordHashField: string,
34
- loginBackgroundImage: string,
35
- userFullnameField: string,
36
- },
37
- emptyFieldPlaceholder?: {
38
- show: string,
39
- list: string,
40
-
41
- } | string,
42
- }
43
-
44
-
45
- export type AllowedActions = {
46
- show: boolean,
47
- create: boolean,
48
- edit: boolean,
49
- delete: boolean,
50
- }
51
-
@@ -1,144 +0,0 @@
1
- import { ref, computed } from 'vue'
2
- import { defineStore } from 'pinia'
3
- import { callAdminForthApi } from '@/utils';
4
- import type { AdminForthResource, AdminForthResourceColumn } from '@/types/AdminForthConfig';
5
- import type { Ref } from 'vue'
6
-
7
- export const useCoreStore = defineStore('core', () => {
8
- const resourceById: Ref<Object> = ref({});
9
- const menu = ref([]);
10
- const config = ref({});
11
- const record: Ref<any | null> = ref({});
12
- const resource: Ref<AdminForthResource | null> = ref(null);
13
-
14
- const resourceColumnsWithFilters = computed(() => {
15
- if (!resource.value) {
16
- return [];
17
- }
18
- return resource.value.columns.filter((col: AdminForthResourceColumn) => col.showIn?.includes('filter'));
19
- })
20
-
21
- const resourceOptions = ref(null);
22
- const resourceColumnsError = ref('');
23
- const resourceColumnsId = ref(null);
24
- const adminUser = ref(null);
25
-
26
- async function fetchMenuAndResource() {
27
- const resp = await callAdminForthApi({
28
- path: '/get_base_config',
29
- method: 'GET',
30
- });
31
- if(!resp){
32
- return
33
- }
34
- menu.value = resp.menu;
35
- resourceById.value = resp.resources.reduce((acc: Object, resource: AdminForthResource) => {
36
- acc[resource.resourceId] = resource;
37
- return acc;
38
- }, {});
39
- config.value = resp.config;
40
- adminUser.value = resp.user;
41
- console.log('🌍 AdminForth v', resp.version);
42
- }
43
-
44
- async function fetchRecord({ resourceId, primaryKey }) {
45
- record.value = null;
46
-
47
- if (!resource.value) {
48
- throw new Error('Columns not fetched yet');
49
- }
50
-
51
- const respData = await callAdminForthApi({
52
- path: '/get_resource_data',
53
- method: 'POST',
54
- body: {
55
- source: 'show',
56
- resourceId: resourceId,
57
- filters: [
58
- {
59
- field: resource.value.columns.find((col: AdminForthResourceColumn) => col.primaryKey).name,
60
- operator: 'eq',
61
- value: primaryKey
62
- }
63
- ],
64
- sort: [],
65
- limit: 1,
66
- offset: 0
67
- }
68
- });
69
-
70
- if (respData.error) {
71
- window.adminforth.alert({
72
- message: respData.error,
73
- variant: 'danger',
74
- timeout: 'unlimited'
75
- });
76
- record.value = {};
77
- } else {
78
- record.value = respData.data[0];
79
- }
80
-
81
- }
82
-
83
- async function fetchResourceFull({ resourceId }: { resourceId: string }) {
84
- if (resourceColumnsId.value === resourceId && resource.value) {
85
- // already fetched
86
- return;
87
- }
88
- resourceColumnsId.value = resourceId;
89
- resourceColumnsError.value = '';
90
- const res = await callAdminForthApi({
91
- path: '/get_resource',
92
- method: 'POST',
93
- body: {
94
- resourceId,
95
- }
96
- });
97
- if (res.error) {
98
- resourceColumnsError.value = res.error;
99
- } else {
100
- resourceById.value[resourceId] = res.resource;
101
- resource.value = res.resource;
102
- resourceOptions.value = res.resource.options;
103
- }
104
- }
105
-
106
- async function getPublicConfig() {
107
- const res = await callAdminForthApi({
108
- path: '/get_public_config',
109
- method: 'GET',
110
- });
111
- config.value = {...config.value, ...res};
112
- }
113
-
114
-
115
-
116
- const username = computed(() => {
117
- const usernameField = config.value.usernameField;
118
- return adminUser.value && adminUser.value[usernameField];
119
- });
120
-
121
- const userFullname = computed(() => {
122
- const userFullnameField = config.value.userFullnameField;
123
- return adminUser.value && adminUser.value[userFullnameField];
124
- })
125
-
126
-
127
- return {
128
- config,
129
- resourceById,
130
- menu,
131
- username,
132
- userFullname,
133
- getPublicConfig,
134
- fetchMenuAndResource,
135
- fetchRecord,
136
- record,
137
- fetchResourceFull,
138
- resourceColumnsError,
139
- resourceOptions,
140
- resource,
141
- adminUser,
142
- resourceColumnsWithFilters
143
- }
144
- })
@@ -1,22 +0,0 @@
1
- import { ref } from 'vue'
2
- import { defineStore } from 'pinia'
3
- import { callAdminForthApi } from '@/utils';
4
-
5
- export const useFiltersStore = defineStore('filters', () => {
6
- const filters = ref([]);
7
- const setFilter = (filter: any) => {
8
- filters.value = [...filters.value, filter];
9
- }
10
- const setFilters = (f: any) => {
11
- filters.value = [...f];
12
- }
13
- const getFilters = () => {
14
- return filters.value;
15
- }
16
- const clearFilters = () => {
17
- filters.value = [];
18
- }
19
- return {setFilter, getFilters,clearFilters, filters,setFilters}
20
- })
21
-
22
-
@@ -1,48 +0,0 @@
1
- import { ref } from 'vue'
2
- import { defineStore } from 'pinia'
3
-
4
- type ModalContentType = {
5
- title?: string;
6
- content?: string;
7
- acceptText?: string;
8
- cancelText?: string;
9
- }
10
-
11
-
12
- export const useModalStore = defineStore('modal', () => {
13
- const modalContent = ref({
14
- title: 'title',
15
- content: 'content',
16
- acceptText: 'acceptText',
17
- cancelText: 'cancelText',
18
- });
19
- const isOpened = ref(false);
20
- const onAcceptFunction: any = ref(()=>{});
21
- const onCancelFunction: any = ref(()=>{});
22
- function togleModal() {
23
- isOpened.value = !isOpened.value;
24
- }
25
- function setOnAcceptFunction(func: Function) {
26
- onAcceptFunction.value = func;
27
- }
28
- function setOnCancelFunction(func: Function) {
29
- onCancelFunction.value = func;
30
- }
31
- function setModalContent(content: ModalContentType) {
32
- modalContent.value = content;
33
- }
34
- function resetmodalState() {
35
- isOpened.value = false;
36
- modalContent.value = {
37
- title: 'title',
38
- content: 'content',
39
- acceptText: 'acceptText',
40
- cancelText: 'cancelText',
41
- };
42
- setOnAcceptFunction(()=>{});
43
-
44
- }
45
-
46
- return {isOpened, setModalContent,onCancelFunction, togleModal,modalContent, setOnAcceptFunction, onAcceptFunction,resetmodalState,setOnCancelFunction}
47
-
48
- })
@@ -1,15 +0,0 @@
1
- import { ref, computed } from 'vue'
2
- import { defineStore } from 'pinia'
3
- import { callAdminForthApi } from '@/utils';
4
- import { v1 as uuid } from 'uuid';
5
-
6
- export const useToastStore = defineStore('toast', () => {
7
- const toasts = ref([]);
8
- const addToast = (toast) => {
9
- toasts.value.push({...toast, id: uuid()});
10
- };
11
- const removeToast = (toast) => {
12
- toasts.value = toasts.value.filter((t) => t.id !== toast.id);
13
- };
14
- return { toasts, addToast, removeToast };
15
- });
@@ -1,54 +0,0 @@
1
- import {ref} from 'vue';
2
- import {defineStore} from 'pinia';
3
- import { callAdminForthApi } from '@/utils';
4
-
5
- export const useUserStore = defineStore('user', () => {
6
- const isAuthorized = ref(false);
7
-
8
- function authorize() {
9
- isAuthorized.value = true;
10
- localStorage.setItem('isAuthorized', 'true');
11
- }
12
-
13
- function unauthorize() {
14
- isAuthorized.value = false;
15
- localStorage.setItem('isAuthorized', 'false');
16
- }
17
-
18
- async function logout() {
19
- await callAdminForthApi({
20
- path: '/logout',
21
- method: 'POST',
22
- });
23
- unauthorize();
24
- }
25
-
26
- // async function checkAuth( skipApiCall = false){
27
- // console.log('checkAuth', isAuthorized.value, skipApiCall)
28
- // if(isAuthorized.value) {
29
- // return true}
30
- // else {
31
- // if(skipApiCall) return false;
32
- // const resp = await callAdminForthApi({
33
- // path: '/check_auth',
34
- // method: 'POST',
35
- // });
36
- // if (resp.status !== 401) {
37
- // authorize();
38
- // return true;
39
- // }
40
- // else {
41
- // unauthorize();
42
- // return false;}
43
- // }
44
-
45
- // }
46
-
47
- return {
48
- isAuthorized,
49
- authorize,
50
- unauthorize,
51
- logout
52
- }
53
-
54
- });
@@ -1,101 +0,0 @@
1
- import { onMounted, ref, resolveComponent } from 'vue';
2
- import type { CoreConfig } from './spa_types/core';
3
-
4
- import router from "./router";
5
- import { useRouter } from 'vue-router';
6
- import { useCoreStore } from './stores/core';
7
- import { useUserStore } from './stores/user';
8
-
9
- export async function callApi({path, method, body=undefined} ) {
10
- const options = {
11
- method,
12
- headers: {
13
- 'Content-Type': 'application/json',
14
- },
15
- body: JSON.stringify(body),
16
- };
17
- const fullPath = `${import.meta.env.VITE_ADMINFORTH_PUBLIC_PATH || ''}${path}`;
18
- const r = await fetch(fullPath, options);
19
- if (r.status == 401) {
20
- useUserStore().unauthorize();
21
- router.push({ name: 'login' });
22
- return null;
23
- }
24
- return await r.json();
25
- }
26
-
27
- export async function callAdminForthApi({ path, method, body=undefined }: {
28
- path: string,
29
- method: 'GET' | 'POST' | 'PUT' | 'DELETE',
30
- body?: any
31
- }) {
32
- try {
33
- return callApi({path: `/adminapi/v1${path}`, method, body} );
34
- } catch (e) {
35
- console.error('error', e);
36
- return { error: `Unexpected error: ${e}` };
37
- }
38
- }
39
-
40
- export function getCustomComponent({ file, meta }: { file: string, meta: any }) {
41
- const name = file.replace(/@/g, '').replace(/\./g, '').replace(/\//g, '');
42
- console.log('resolving name', name);
43
- return resolveComponent(name);
44
- }
45
-
46
- export function getIcon(icon: string) {
47
- // icon format is "feather:icon-name". We need to get IconName in pascal case
48
- if (!icon.includes(':')) {
49
- throw new Error('Icon name should be in format "icon-set:icon-name"');
50
- }
51
- const [iconSet, iconName] = icon.split(':');
52
- const compName = 'Icon' + iconName.split('-').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join('');
53
- return resolveComponent(compName);
54
- }
55
-
56
- export const loadFile = (file: string) => {
57
- if (file.startsWith('http')) {
58
- return file;
59
- }
60
- let path;
61
- let baseUrl = '';
62
- if (file.startsWith('@/')) {
63
- path = file.replace('@/', '');
64
- baseUrl = new URL(`./${path}`, import.meta.url).href;
65
- } else if (file.startsWith('@@/')) {
66
- path = file.replace('@@/', '');
67
- baseUrl = new URL(`./custom/${path}`, import.meta.url).href;
68
- } else {
69
- baseUrl = new URL(`./${file}`, import.meta.url).href;
70
- }
71
- return baseUrl;
72
- }
73
-
74
- export function checkEmptyValues(value: any, viewType:'show' | 'list' ) {
75
- const config: CoreConfig | {} = useCoreStore().config;
76
- let emptyFieldPlaceholder = '';
77
- if (config.emptyFieldPlaceholder) {
78
- if(typeof config.emptyFieldPlaceholder === 'string') {
79
- emptyFieldPlaceholder = config.emptyFieldPlaceholder;
80
- } else {
81
- emptyFieldPlaceholder = config.emptyFieldPlaceholder?.[viewType] || '';
82
- }
83
- if (value === null || value === undefined || value === '') {
84
- return emptyFieldPlaceholder;
85
- }
86
- }
87
- return value;
88
- }
89
-
90
- export function checkAcessByAllowedActions(allowedActions:any, action:any ) {
91
- if (!allowedActions) {
92
- console.warn('allowedActions not set');
93
- return;
94
- }
95
- if(allowedActions[action] === false) {
96
- console.warn(`Action ${action} is not allowed`);
97
- router.back();
98
- }
99
- }
100
-
101
-