adminforth 1.17.0 → 1.19.0
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/commands/createApp/utils.js +30 -19
- package/commands/createPlugin/templates/index.ts.hbs +1 -1
- package/dist/spa/src/afcl/Dropzone.vue +14 -3
- package/dist/spa/src/renderers/CompactField.vue +3 -1
- package/dist/spa/src/renderers/CompactUUID.vue +3 -1
- package/dist/spa/src/types/Adapters.ts +15 -0
- package/dist/spa/src/types/Back.ts +1 -1
- package/dist/spa/src/views/EditView.vue +3 -1
- package/dist/spa/src/views/ListView.vue +1 -5
- package/dist/types/Adapters.d.ts +7 -0
- package/dist/types/Adapters.d.ts.map +1 -1
- package/dist/types/Back.d.ts +1 -1
- package/package.json +1 -1
|
@@ -96,7 +96,7 @@ function generateDbUrlForPrisma(connectionString) {
|
|
|
96
96
|
return connectionString.toString();
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
function initialChecks() {
|
|
99
|
+
function initialChecks(options) {
|
|
100
100
|
return [
|
|
101
101
|
{
|
|
102
102
|
title: '👀 Checking Node.js version...',
|
|
@@ -104,21 +104,25 @@ function initialChecks() {
|
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
title: '👀 Validating current working directory...',
|
|
107
|
-
task: () => checkForExistingPackageJson()
|
|
107
|
+
task: () => checkForExistingPackageJson(options)
|
|
108
108
|
}
|
|
109
109
|
]
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function checkForExistingPackageJson() {
|
|
113
|
-
|
|
112
|
+
function checkForExistingPackageJson(options) {
|
|
113
|
+
const projectDir = path.join(process.cwd(), options.appName);
|
|
114
|
+
if (fs.existsSync(projectDir)) {
|
|
114
115
|
throw new Error(
|
|
115
|
-
`
|
|
116
|
-
`Please remove it or use
|
|
116
|
+
`Directory "${options.appName}" already exists.\n` +
|
|
117
|
+
`Please remove it or use a different name.`
|
|
117
118
|
);
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
async function scaffoldProject(ctx, options, cwd) {
|
|
123
|
+
const projectDir = path.join(cwd, options.appName);
|
|
124
|
+
await fse.ensureDir(projectDir);
|
|
125
|
+
|
|
122
126
|
const connectionString = parseConnectionString(options.db);
|
|
123
127
|
const provider = detectDbProvider(connectionString.protocol);
|
|
124
128
|
const prismaDbUrl = generateDbUrlForPrisma(connectionString);
|
|
@@ -130,9 +134,9 @@ async function scaffoldProject(ctx, options, cwd) {
|
|
|
130
134
|
const dirname = path.dirname(filename);
|
|
131
135
|
|
|
132
136
|
// Prepare directories
|
|
133
|
-
ctx.customDir = path.join(
|
|
137
|
+
ctx.customDir = path.join(projectDir, 'custom');
|
|
134
138
|
await fse.ensureDir(ctx.customDir);
|
|
135
|
-
await fse.ensureDir(path.join(
|
|
139
|
+
await fse.ensureDir(path.join(projectDir, 'resources'));
|
|
136
140
|
|
|
137
141
|
// Copy static assets to `custom/assets`
|
|
138
142
|
const sourceAssetsDir = path.join(dirname, 'assets');
|
|
@@ -141,13 +145,14 @@ async function scaffoldProject(ctx, options, cwd) {
|
|
|
141
145
|
await fse.copy(sourceAssetsDir, targetAssetsDir);
|
|
142
146
|
|
|
143
147
|
// Write templated files
|
|
144
|
-
writeTemplateFiles(dirname,
|
|
148
|
+
writeTemplateFiles(dirname, projectDir, {
|
|
145
149
|
dbUrl: connectionString.toString(),
|
|
146
150
|
prismaDbUrl,
|
|
147
151
|
appName,
|
|
148
152
|
provider,
|
|
149
153
|
});
|
|
150
154
|
|
|
155
|
+
return projectDir; // Return the new directory path
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
async function writeTemplateFiles(dirname, cwd, options) {
|
|
@@ -236,14 +241,18 @@ async function installDependencies(ctx, cwd) {
|
|
|
236
241
|
const customDir = ctx.customDir;
|
|
237
242
|
|
|
238
243
|
await Promise.all([
|
|
239
|
-
await execa('npm', ['install'
|
|
244
|
+
await execa('npm', ['install'], { cwd }),
|
|
240
245
|
await execa('npm', ['install'], { cwd: customDir }),
|
|
241
246
|
]);
|
|
242
247
|
}
|
|
243
248
|
|
|
244
|
-
function generateFinalInstructions(skipPrismaSetup) {
|
|
249
|
+
function generateFinalInstructions(skipPrismaSetup, options) {
|
|
245
250
|
let instruction = '⏭️ Run the following commands to get started:\n';
|
|
246
251
|
if (!skipPrismaSetup)
|
|
252
|
+
instruction += `
|
|
253
|
+
${chalk.dim('// Go to the project directory')}
|
|
254
|
+
${chalk.cyan(`$ cd ${options.appName}`)}\n`;
|
|
255
|
+
|
|
247
256
|
instruction += `
|
|
248
257
|
${chalk.dim('// Generate and apply initial migration')}
|
|
249
258
|
${chalk.cyan('$ npm run makemigration -- --name init')}\n`;
|
|
@@ -272,33 +281,35 @@ export function prepareWorkflow(options) {
|
|
|
272
281
|
title: '🔍 Initial checks...',
|
|
273
282
|
task: (_, task) =>
|
|
274
283
|
task.newListr(
|
|
275
|
-
initialChecks(),
|
|
284
|
+
initialChecks(options),
|
|
276
285
|
{ concurrent: true },
|
|
277
286
|
)
|
|
278
287
|
},
|
|
279
288
|
{
|
|
280
289
|
title: '🚀 Scaffolding your project...',
|
|
281
|
-
task: async (ctx) =>
|
|
290
|
+
task: async (ctx) => {
|
|
291
|
+
ctx.projectDir = await scaffoldProject(ctx, options, cwd);
|
|
292
|
+
}
|
|
282
293
|
},
|
|
283
294
|
{
|
|
284
295
|
title: '📦 Installing dependencies...',
|
|
285
|
-
task: async (ctx) => installDependencies(ctx,
|
|
296
|
+
task: async (ctx) => installDependencies(ctx, ctx.projectDir)
|
|
286
297
|
},
|
|
287
298
|
{
|
|
288
299
|
title: '📝 Preparing final instructions...',
|
|
289
300
|
task: (ctx) => {
|
|
290
|
-
console.log(chalk.green(`✅ Successfully created your new Adminforth project!\n`));
|
|
291
|
-
console.log(generateFinalInstructions(ctx.skipPrismaSetup));
|
|
301
|
+
console.log(chalk.green(`✅ Successfully created your new Adminforth project in ${ctx.projectDir}!\n`));
|
|
302
|
+
console.log(generateFinalInstructions(ctx.skipPrismaSetup, options));
|
|
292
303
|
console.log('\n\n');
|
|
304
|
+
}
|
|
293
305
|
}
|
|
294
|
-
|
|
306
|
+
],
|
|
295
307
|
{
|
|
296
308
|
rendererOptions: {collapseSubtasks: false},
|
|
297
309
|
concurrent: false,
|
|
298
310
|
exitOnError: true,
|
|
299
311
|
collectErrors: true,
|
|
300
|
-
}
|
|
301
|
-
);
|
|
312
|
+
});
|
|
302
313
|
|
|
303
314
|
return tasks;
|
|
304
315
|
}
|
|
@@ -3,7 +3,7 @@ import type { IAdminForth, IHttpServer, AdminForthResourcePages, AdminForthResou
|
|
|
3
3
|
import type { PluginOptions } from './types.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
export default class
|
|
6
|
+
export default class {{pluginName}} extends AdminForthPlugin {
|
|
7
7
|
options: PluginOptions;
|
|
8
8
|
|
|
9
9
|
constructor(options: PluginOptions) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<!-- tag form used to reset the input (method .reset() in claer() function) -->
|
|
3
|
+
<form class="flex items-center justify-center w-full"
|
|
3
4
|
@dragover.prevent="dragging = true"
|
|
4
5
|
@dragleave.prevent="dragging = false"
|
|
5
6
|
@drop.prevent="dragging = false; doEmit($event.dataTransfer.files)"
|
|
@@ -43,12 +44,12 @@
|
|
|
43
44
|
:multiple="props.multiple || false"
|
|
44
45
|
/>
|
|
45
46
|
</label>
|
|
46
|
-
|
|
47
|
+
</form>
|
|
47
48
|
</template>
|
|
48
49
|
|
|
49
50
|
<script setup lang="ts">
|
|
50
51
|
import { humanifySize } from '@/utils';
|
|
51
|
-
import { ref, type Ref } from 'vue';
|
|
52
|
+
import { ref, defineExpose, type Ref } from 'vue';
|
|
52
53
|
import { IconFileSolid } from '@iconify-prerendered/vue-flowbite';
|
|
53
54
|
import { watch } from 'vue';
|
|
54
55
|
import adminforth from '@/adminforth';
|
|
@@ -125,4 +126,14 @@ function doEmit(filesIn: FileList) {
|
|
|
125
126
|
|
|
126
127
|
const dragging = ref(false);
|
|
127
128
|
|
|
129
|
+
function clear() {
|
|
130
|
+
selectedFiles.value = [];
|
|
131
|
+
emit('update:modelValue', []);
|
|
132
|
+
const form = document.getElementById(id)?.closest('form');
|
|
133
|
+
form?.reset();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
defineExpose({
|
|
137
|
+
clear,
|
|
138
|
+
});
|
|
128
139
|
</script>
|
|
@@ -16,7 +16,9 @@ import { computed, ref, onMounted, nextTick } from 'vue';
|
|
|
16
16
|
import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
|
|
17
17
|
import Tooltip from '@/afcl/Tooltip.vue';
|
|
18
18
|
import adminforth from '@/adminforth';
|
|
19
|
+
import { useI18n } from 'vue-i18n';
|
|
19
20
|
|
|
21
|
+
const { t } = useI18n();
|
|
20
22
|
const visualValue = computed(() => {
|
|
21
23
|
// if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
|
|
22
24
|
const val = props.record[props.column.name];
|
|
@@ -33,7 +35,7 @@ const id = ref();
|
|
|
33
35
|
function copyToCB() {
|
|
34
36
|
navigator.clipboard.writeText(props.record[props.column.name]);
|
|
35
37
|
adminforth.alert({
|
|
36
|
-
message: 'ID copied to clipboard',
|
|
38
|
+
message: t('ID copied to clipboard'),
|
|
37
39
|
variant: 'success',
|
|
38
40
|
})
|
|
39
41
|
}
|
|
@@ -16,7 +16,9 @@ import { computed, ref, onMounted, nextTick } from 'vue';
|
|
|
16
16
|
import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
|
|
17
17
|
import Tooltip from '@/afcl/Tooltip.vue';
|
|
18
18
|
import adminforth from '@/adminforth';
|
|
19
|
+
import { useI18n } from 'vue-i18n';
|
|
19
20
|
|
|
21
|
+
const { t } = useI18n();
|
|
20
22
|
const visualValue = computed(() => {
|
|
21
23
|
// if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
|
|
22
24
|
const val = props.record[props.column.name];
|
|
@@ -33,7 +35,7 @@ const id = ref();
|
|
|
33
35
|
function copyToCB() {
|
|
34
36
|
navigator.clipboard.writeText(props.record[props.column.name]);
|
|
35
37
|
adminforth.alert({
|
|
36
|
-
message: 'ID copied to clipboard',
|
|
38
|
+
message: t('ID copied to clipboard'),
|
|
37
39
|
variant: 'success',
|
|
38
40
|
})
|
|
39
41
|
}
|
|
@@ -28,6 +28,21 @@ export interface CompletionAdapter {
|
|
|
28
28
|
}>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export interface ImageGenerationAdapter {
|
|
32
|
+
|
|
33
|
+
validate(): void;
|
|
34
|
+
|
|
35
|
+
generate(
|
|
36
|
+
prompt: string,
|
|
37
|
+
inputFiles: string[],
|
|
38
|
+
): Promise<{
|
|
39
|
+
imageURL?: string;
|
|
40
|
+
error?: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
31
46
|
export interface OAuth2Adapter {
|
|
32
47
|
getAuthUrl(): string;
|
|
33
48
|
getTokenFromCode(code: string, redirect_uri: string): Promise<{ email: string }>;
|
|
@@ -386,7 +386,7 @@ export interface IAdminForth {
|
|
|
386
386
|
* Example:
|
|
387
387
|
*
|
|
388
388
|
* ```ts
|
|
389
|
-
* const i18nPlugin = adminforth.getPluginByClassName
|
|
389
|
+
* const i18nPlugin = adminforth.getPluginByClassName\<I18nPlugin\>('I18nPlugin');
|
|
390
390
|
* ```
|
|
391
391
|
*
|
|
392
392
|
*/
|
|
@@ -81,7 +81,9 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
81
81
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
82
82
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
83
83
|
import adminforth from '@/adminforth';
|
|
84
|
+
import { useI18n } from 'vue-i18n';
|
|
84
85
|
|
|
86
|
+
const { t } = useI18n();
|
|
85
87
|
const coreStore = useCoreStore();
|
|
86
88
|
|
|
87
89
|
const isValid = ref(false);
|
|
@@ -170,7 +172,7 @@ async function saveRecord() {
|
|
|
170
172
|
showErrorTost(resp.error);
|
|
171
173
|
} else {
|
|
172
174
|
adminforth.alert({
|
|
173
|
-
message: 'Record updated successfully',
|
|
175
|
+
message: t('Record updated successfully'),
|
|
174
176
|
variant: 'success',
|
|
175
177
|
timeout: 400000
|
|
176
178
|
});
|
|
@@ -331,7 +331,7 @@ async function init() {
|
|
|
331
331
|
await coreStore.fetchResourceFull({
|
|
332
332
|
resourceId: route.params.resourceId
|
|
333
333
|
});
|
|
334
|
-
|
|
334
|
+
isPageLoaded.value = true;
|
|
335
335
|
// !!! clear filters should be in same tick with sort assignment so that watch can catch it as one change
|
|
336
336
|
|
|
337
337
|
// try to init filters from query params
|
|
@@ -446,8 +446,4 @@ watch([sort], async () => {
|
|
|
446
446
|
setQuery({ sort: SortQuerySerializer.serialize(sort.value) });
|
|
447
447
|
});
|
|
448
448
|
|
|
449
|
-
watch(() => coreStore.resource, () => {
|
|
450
|
-
isPageLoaded.value = true;
|
|
451
|
-
});
|
|
452
|
-
|
|
453
449
|
</script>
|
package/dist/types/Adapters.d.ts
CHANGED
|
@@ -13,6 +13,13 @@ export interface CompletionAdapter {
|
|
|
13
13
|
error?: string;
|
|
14
14
|
}>;
|
|
15
15
|
}
|
|
16
|
+
export interface ImageGenerationAdapter {
|
|
17
|
+
validate(): void;
|
|
18
|
+
generate(prompt: string, inputFiles: string[]): Promise<{
|
|
19
|
+
imageURL?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
16
23
|
export interface OAuth2Adapter {
|
|
17
24
|
getAuthUrl(): string;
|
|
18
25
|
getTokenFromCode(code: string, redirect_uri: string): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Adapters.d.ts","sourceRoot":"","sources":["../../types/Adapters.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,EAAE,CAAC,EAAE,OAAO,CAAC;KACd,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,IAAI,IAAI,CAAC;IAEjB,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,IAAI,MAAM,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,OAAO,IAAI,MAAM,CAAC;IAClB,aAAa,CAAC,IAAI,MAAM,CAAC;IACzB,OAAO,CAAC,IAAI,MAAM,CAAC;CACpB"}
|
|
1
|
+
{"version":3,"file":"Adapters.d.ts","sourceRoot":"","sources":["../../types/Adapters.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,EAAE,CAAC,EAAE,OAAO,CAAC;KACd,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,IAAI,IAAI,CAAC;IAEjB,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,sBAAsB;IAErC,QAAQ,IAAI,IAAI,CAAC;IAEjB,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC;QACT,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAID,MAAM,WAAW,aAAa;IAC5B,UAAU,IAAI,MAAM,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,OAAO,IAAI,MAAM,CAAC;IAClB,aAAa,CAAC,IAAI,MAAM,CAAC;IACzB,OAAO,CAAC,IAAI,MAAM,CAAC;CACpB"}
|
package/dist/types/Back.d.ts
CHANGED
|
@@ -367,7 +367,7 @@ export interface IAdminForth {
|
|
|
367
367
|
* Example:
|
|
368
368
|
*
|
|
369
369
|
* ```ts
|
|
370
|
-
* const i18nPlugin = adminforth.getPluginByClassName
|
|
370
|
+
* const i18nPlugin = adminforth.getPluginByClassName\<I18nPlugin\>('I18nPlugin');
|
|
371
371
|
* ```
|
|
372
372
|
*
|
|
373
373
|
*/
|