adminforth 1.5.5-next.3 → 1.5.5-next.5

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.
@@ -173,7 +173,7 @@
173
173
  </div>
174
174
 
175
175
  <div v-else-if="routerIsReady && loginRedirectCheckIsReady && publicConfigLoaded">
176
- <RouterView/>
176
+ <RouterView />
177
177
  </div>
178
178
 
179
179
  <div v-else class="flex items-center justify-center h-screen">
@@ -268,7 +268,7 @@ const sidebarAside = ref(null);
268
268
  const routerIsReady = ref(false);
269
269
  const loginRedirectCheckIsReady = ref(false);
270
270
 
271
- const loggedIn = computed(() => route.name !== 'login');
271
+ const loggedIn = computed(() => !!coreStore?.adminUser);
272
272
 
273
273
  const theme = ref('light');
274
274
 
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <div class="flex items-center h-5">
3
+ <input :id="id"
4
+ ref="rememberInput"
5
+ type="checkbox"
6
+ :checked="props.modelValue"
7
+ @change="$emit('update:modelValue', $event.target.checked)"
8
+ class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-lightPrimary focus:ring-opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 checked:bg-lightPrimary checked:dark:bg-darkPrimary" />
9
+ </div>
10
+ <label :for="id" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">
11
+ <slot></slot>
12
+ </label>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+
17
+ const props = defineProps({
18
+ modelValue: Boolean,
19
+ });
20
+
21
+ defineEmits(['update:modelValue']);
22
+
23
+ const id = `afcb-${Math.random().toString(36).substring(7)}`
24
+ </script>
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <div class="flex items-center justify-center w-full"
3
+ @dragover.prevent="dragging = true"
4
+ @dragleave.prevent="dragging = false"
5
+ @drop.prevent="dragging = false; doEmit($event.dataTransfer.files)"
6
+ >
7
+ <label :id="id" class="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed rounded-lg cursor-pointer dark:hover:bg-gray-800
8
+ hover:bg-gray-100 dark:hover:border-gray-500 dark:hover:bg-gray-600"
9
+ :class="{
10
+ 'border-blue-600 dark:border-blue-400': dragging,
11
+ 'border-gray-300 dark:border-gray-600': !dragging,
12
+ 'bg-blue-50 dark:bg-blue-800': dragging,
13
+ 'bg-gray-50 dark:bg-gray-800': !dragging,
14
+ }"
15
+ >
16
+ <div class="flex flex-col items-center justify-center pt-5 pb-6">
17
+
18
+
19
+ <svg v-if="!selectedFiles.length" class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
20
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"/>
21
+ </svg>
22
+ <div v-else class="flex items-center justify-center w-full mt-1 mb-4">
23
+ <template v-for="file in selectedFiles">
24
+ <p class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
25
+ <IconFileSolid class="w-5 h-5" />
26
+ {{ file.name }} ({{ humanifySize(file.size) }})
27
+ </p>
28
+ </template>
29
+
30
+ </div>
31
+
32
+ <p v-if="!selectedFiles.length" class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span class="font-semibold">Click to upload</span> or drag and drop</p>
33
+ <p class="text-xs text-gray-500 dark:text-gray-400">
34
+ {{ props.extensions.join(', ').toUpperCase().replace(/\./g, '') }}
35
+ <template v-if="props.maxSizeBytes">
36
+ (Max size: {{ humanifySize(props.maxSizeBytes) }})
37
+ </template>
38
+ </p>
39
+ </div>
40
+ <input :id="id" type="file" class="hidden"
41
+ :accept="props.extensions.join(', ')"
42
+ @change="doEmit($event.target.files)"
43
+ :multiple="props.multiple || false"
44
+ />
45
+ </label>
46
+ </div>
47
+ </template>
48
+
49
+ <script setup lang="ts">
50
+ import { humanifySize } from '@/utils';
51
+ import { ref } from 'vue';
52
+ import { IconFileSolid } from '@iconify-prerendered/vue-flowbite';
53
+
54
+ const props = defineProps<{
55
+ extensions: string[],
56
+ maxSizeBytes: number,
57
+ multiple: boolean,
58
+ modelValue: FileList,
59
+ }>();
60
+
61
+ const emit = defineEmits(['update:modelValue']);
62
+
63
+ const id = `afcl-dropzone-${Math.random().toString(36).substring(7)}`;
64
+
65
+ const selectedFiles: Ref<{
66
+ name: string,
67
+ size: number,
68
+ mime: string,
69
+ }[]> = ref([]);
70
+
71
+ watch(() => props.modelValue, (files) => {
72
+ selectedFiles.value = Array.from(files).map(file => ({
73
+ name: file.name,
74
+ size: file.size,
75
+ mime: file.type,
76
+ }));
77
+ });
78
+
79
+ function doEmit(filesIn: FileList) {
80
+
81
+ const multiple = props.multiple || false;
82
+ const files = Array.from(filesIn);
83
+ if (!files.length) return;
84
+ if (!multiple) {
85
+ files.splice(1);
86
+ }
87
+ selectedFiles.value = files.map(file => ({
88
+ name: file.name,
89
+ size: file.size,
90
+ mime: file.type,
91
+ }));
92
+
93
+ emit('update:modelValue', Array.from(files));
94
+ }
95
+
96
+ const dragging = ref(false);
97
+
98
+ </script>
@@ -43,6 +43,11 @@
43
43
  <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-gray-400 dark:text-gray-300">
44
44
  No results found
45
45
  </div>
46
+
47
+ <div v-if="$slots['extra-item']" class="px-4 py-2 dark:text-gray-400">
48
+ <slot name="extra-item"></slot>
49
+ </div>
50
+
46
51
  </div>
47
52
 
48
53
  <div v-if="multiple && selectedItems.length"
@@ -6,4 +6,6 @@ export { default as Button } from './Button.vue';
6
6
  export { default as Input } from './Input.vue';
7
7
  export { default as Tooltip } from './Tooltip.vue';
8
8
  export { default as LinkButton } from './LinkButton.vue';
9
- export { default as VerticalTabs } from './VerticalTabs.vue';
9
+ export { default as VerticalTabs } from './VerticalTabs.vue';
10
+ export { default as Checkbox } from './Checkbox.vue';
11
+ export { default as Dropzone } from './Dropzone.vue';
@@ -449,7 +449,6 @@ async function deleteRecord(row) {
449
449
  primaryKey: row._primaryKeyValue,
450
450
  }
451
451
  });
452
- console.log('safsa', res)
453
452
  if (!res.error){
454
453
  emits('update:records', true)
455
454
  showSuccesTost('Record deleted successfully')
@@ -49,6 +49,7 @@ export const useCoreStore = defineStore('core', () => {
49
49
  path: '/get_base_config',
50
50
  method: 'GET',
51
51
  });
52
+
52
53
  if(!resp){
53
54
  return
54
55
  }
@@ -24,7 +24,7 @@ export async function callApi({path, method, body=undefined}: {
24
24
  const r = await fetch(fullPath, options);
25
25
  if (r.status == 401 ) {
26
26
  useUserStore().unauthorize();
27
- router.push({ name: 'login' });
27
+ await router.push({ name: 'login' });
28
28
  return null;
29
29
  }
30
30
  return await r.json();
@@ -161,4 +161,17 @@ export function setQuery(query: any) {
161
161
 
162
162
  export function verySimpleHash(str: string): string {
163
163
  return `${str.split('').reduce((a, b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)}`;
164
- }
164
+ }
165
+
166
+ export function humanifySize(size) {
167
+ if (!size) {
168
+ return '';
169
+ }
170
+ const units = ['B', 'KB', 'MB', 'GB', 'TB']
171
+ let i = 0
172
+ while (size >= 1024 && i < units.length - 1) {
173
+ size /= 1024
174
+ i++
175
+ }
176
+ return `${size.toFixed(1)} ${units[i]}`
177
+ }
@@ -108,7 +108,6 @@ const initalValues = computed(() => {
108
108
  });
109
109
 
110
110
 
111
-
112
111
  async function onUpdateRecord(newRecord) {
113
112
  console.log('newRecord', newRecord);
114
113
  record.value = newRecord;
@@ -65,14 +65,10 @@
65
65
  class="flex items-start mb-5"
66
66
  :title="`Stay logged in for ${coreStore.config.rememberMeDays} days`"
67
67
  >
68
- <div class="flex items-center h-5">
69
- <input id="remember"
70
- ref="rememberInput"
71
- type="checkbox"
72
- value=""
73
- class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-lightPrimary focus:ring-opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 checked:bg-lightPrimary checked:dark:bg-darkPrimary" />
74
- </div>
75
- <label for="remember" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Remember me</label>
68
+ <Checkbox v-model="rememberMeValue" class="mr-2">
69
+ Remember me
70
+ </Checkbox>
71
+
76
72
  </div>
77
73
 
78
74
  <component
@@ -123,11 +119,11 @@ import { useUserStore } from '@/stores/user';
123
119
  import { IconEyeSolid, IconEyeSlashSolid } from '@iconify-prerendered/vue-flowbite';
124
120
  import { callAdminForthApi, loadFile } from '@/utils';
125
121
  import { useRouter } from 'vue-router';
126
- import { Button } from '@/afcl';
122
+ import { Button, Checkbox } from '@/afcl';
127
123
 
128
124
  const passwordInput = ref(null);
129
125
  const usernameInput = ref(null);
130
- const rememberInput = ref(null);
126
+ const rememberMeValue= ref(false);
131
127
 
132
128
  const router = useRouter();
133
129
  const inProgress = ref(false);
@@ -172,7 +168,7 @@ async function login() {
172
168
  body: {
173
169
  username,
174
170
  password,
175
- rememberMe: rememberInput.value?.checked,
171
+ rememberMe: rememberMeValue.value,
176
172
  }
177
173
  });
178
174
  if (resp.error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.5.5-next.3",
3
+ "version": "1.5.5-next.5",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -22,8 +22,8 @@
22
22
  "rollout-next": "npm run build && npm version prerelease --preid=next && npm publish --tag next && npm run put-git-tag",
23
23
  "rollout-doc": "cd documentation && npm run build && npm run deploy",
24
24
  "docs": "typedoc",
25
- "--comment_postinstall": "postinstall executed after package installed in other project package",
26
- "postinstall": "cd ./dist/spa/ && npm ci && echo 'installed spa dependencies'",
25
+ "--comment_postinstall": "postinstall executed after package installed in other project package and when we do npm ci in the package",
26
+ "postinstall": "if test -d ./dist/spa/; then cd ./dist/spa/ && npm ci && echo 'installed spa dependencies'; fi",
27
27
  "ci-plugins": "for d in plugins/*; do cd $d && npm ci && cd ../..; done"
28
28
  },
29
29
  "exports": {