Skip to content

Commit 006e51b

Browse files
authored
Merge pull request #195 from devforth/next
Next
2 parents 96a1785 + a712e99 commit 006e51b

File tree

8 files changed

+71
-38
lines changed

8 files changed

+71
-38
lines changed

adminforth/commands/createApp/utils.js

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,33 @@ function generateDbUrlForPrisma(connectionString) {
9696
return connectionString.toString();
9797
}
9898

99-
function initialChecks() {
99+
function initialChecks(options) {
100100
return [
101101
{
102102
title: '👀 Checking Node.js version...',
103103
task: () => checkNodeVersion(20)
104104
},
105105
{
106106
title: '👀 Validating current working directory...',
107-
task: () => checkForExistingPackageJson()
107+
task: () => checkForExistingPackageJson(options)
108108
}
109109
]
110110
}
111111

112-
function checkForExistingPackageJson() {
113-
if (fs.existsSync(path.join(process.cwd(), 'package.json'))) {
112+
function checkForExistingPackageJson(options) {
113+
const projectDir = path.join(process.cwd(), options.appName);
114+
if (fs.existsSync(projectDir)) {
114115
throw new Error(
115-
`A package.json already exists in this directory.\n` +
116-
`Please remove it or use an empty directory.`
116+
`Directory "${options.appName}" already exists.\n` +
117+
`Please remove it or use a different name.`
117118
);
118119
}
119120
}
120121

121122
async function scaffoldProject(ctx, options, cwd) {
123+
const projectDir = path.join(cwd, options.appName);
124+
await fse.ensureDir(projectDir);
125+
122126
const connectionString = parseConnectionString(options.db);
123127
const provider = detectDbProvider(connectionString.protocol);
124128
const prismaDbUrl = generateDbUrlForPrisma(connectionString);
@@ -130,9 +134,9 @@ async function scaffoldProject(ctx, options, cwd) {
130134
const dirname = path.dirname(filename);
131135

132136
// Prepare directories
133-
ctx.customDir = path.join(cwd, 'custom');
137+
ctx.customDir = path.join(projectDir, 'custom');
134138
await fse.ensureDir(ctx.customDir);
135-
await fse.ensureDir(path.join(cwd, 'resources'));
139+
await fse.ensureDir(path.join(projectDir, 'resources'));
136140

137141
// Copy static assets to `custom/assets`
138142
const sourceAssetsDir = path.join(dirname, 'assets');
@@ -141,13 +145,14 @@ async function scaffoldProject(ctx, options, cwd) {
141145
await fse.copy(sourceAssetsDir, targetAssetsDir);
142146

143147
// Write templated files
144-
writeTemplateFiles(dirname, cwd, {
148+
writeTemplateFiles(dirname, projectDir, {
145149
dbUrl: connectionString.toString(),
146150
prismaDbUrl,
147151
appName,
148152
provider,
149153
});
150154

155+
return projectDir; // Return the new directory path
151156
}
152157

153158
async function writeTemplateFiles(dirname, cwd, options) {
@@ -241,9 +246,13 @@ async function installDependencies(ctx, cwd) {
241246
]);
242247
}
243248

244-
function generateFinalInstructions(skipPrismaSetup) {
249+
function generateFinalInstructions(skipPrismaSetup, options) {
245250
let instruction = '⏭️ Run the following commands to get started:\n';
246251
if (!skipPrismaSetup)
252+
instruction += `
253+
${chalk.dim('// Go to the project directory')}
254+
${chalk.cyan(`$ cd ${options.appName}`)}\n`;
255+
247256
instruction += `
248257
${chalk.dim('// Generate and apply initial migration')}
249258
${chalk.cyan('$ npm run makemigration -- --name init')}\n`;
@@ -272,33 +281,35 @@ export function prepareWorkflow(options) {
272281
title: '🔍 Initial checks...',
273282
task: (_, task) =>
274283
task.newListr(
275-
initialChecks(),
284+
initialChecks(options),
276285
{ concurrent: true },
277286
)
278287
},
279288
{
280289
title: '🚀 Scaffolding your project...',
281-
task: async (ctx) => scaffoldProject(ctx, options, cwd)
290+
task: async (ctx) => {
291+
ctx.projectDir = await scaffoldProject(ctx, options, cwd);
292+
}
282293
},
283294
{
284295
title: '📦 Installing dependencies...',
285-
task: async (ctx) => installDependencies(ctx, cwd)
296+
task: async (ctx) => installDependencies(ctx, ctx.projectDir)
286297
},
287298
{
288299
title: '📝 Preparing final instructions...',
289300
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));
292303
console.log('\n\n');
304+
}
293305
}
294-
}],
306+
],
295307
{
296308
rendererOptions: {collapseSubtasks: false},
297309
concurrent: false,
298310
exitOnError: true,
299311
collectErrors: true,
300-
}
301-
);
312+
});
302313

303314
return tasks;
304315
}

adminforth/commands/createPlugin/templates/index.ts.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { IAdminForth, IHttpServer, AdminForthResourcePages, AdminForthResou
33
import type { PluginOptions } from './types.js';
44

55

6-
export default class ChatGptPlugin extends AdminForthPlugin {
6+
export default class {{pluginName}} extends AdminForthPlugin {
77
options: PluginOptions;
88

99
constructor(options: PluginOptions) {

adminforth/spa/src/views/ListView.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ async function init() {
331331
await coreStore.fetchResourceFull({
332332
resourceId: route.params.resourceId
333333
});
334-
334+
isPageLoaded.value = true;
335335
// !!! clear filters should be in same tick with sort assignment so that watch can catch it as one change
336336
337337
// try to init filters from query params
@@ -446,8 +446,4 @@ watch([sort], async () => {
446446
setQuery({ sort: SortQuerySerializer.serialize(sort.value) });
447447
});
448448
449-
watch(() => coreStore.resource, () => {
450-
isPageLoaded.value = true;
451-
});
452-
453449
</script>

adminforth/types/Adapters.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ export interface CompletionAdapter {
2828
}>;
2929
}
3030

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+
3146
export interface OAuth2Adapter {
3247
getAuthUrl(): string;
3348
getTokenFromCode(code: string, redirect_uri: string): Promise<{ email: string }>;

dev-demo/.env.local

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ KEYCLOAK_URL=http://localhost:8080
22

33
ADMINFORTH_SECRET=123
44
NODE_ENV=development
5-
DATABASE_URL=sqlite://.db.sqlite
6-
PRISMA_DATABASE_URL=file:.db.sqlite
5+
DATABASE_URL=sqlite://./.db.sqlite
6+
DATABASE_FILE_URL=file:.db.sqlite

dev-demo/index.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import betterSqlite3 from 'better-sqlite3';
22
import express from 'express';
33
import AdminForth, { AdminUser, Filters } from '../adminforth/index.js';
44

5-
import AuditLogPlugin from '../plugins/adminforth-audit-log/index.js';
65
import clicksResource from './resources/clicks.js';
76
import apartmentsResource from './resources/apartments.js';
87
import apartmentBuyersResource from './resources/apartment_buyers.js';
@@ -18,15 +17,24 @@ import providersResource from './resources/providers.js';
1817
import apiKeysResource from './resources/api_keys.js';
1918
import CompletionAdapterOpenAIChatGPT from '../adapters/adminforth-completion-adapter-open-ai-chat-gpt/index.js';
2019
import pkg from 'pg';
20+
import I18nPlugin from '../plugins/adminforth-i18n/index.js';
2121
const { Client } = pkg;
2222

23+
24+
declare global {
25+
namespace NodeJS {
26+
interface ProcessEnv {
27+
NODE_ENV: string;
28+
DATABASE_URL: string;
29+
OPENAI_API_KEY: string;
30+
PORT: string;
31+
}
32+
}
33+
}
34+
2335
// const ADMIN_BASE_URL = '/portal';
2436
const ADMIN_BASE_URL = '';
2537

26-
// create test1.db
27-
const dbPath = 'db.sqlite';
28-
const db = betterSqlite3(dbPath)
29-
3038
async function seedDatabase() {
3139

3240
const adapter = new CompletionAdapterOpenAIChatGPT({
@@ -182,7 +190,7 @@ export const admin = new AdminForth({
182190
dataSources: [
183191
{
184192
id: 'maindb',
185-
url: `sqlite://${dbPath}`
193+
url: process.env.DATABASE_URL,
186194
},
187195
{
188196
id: 'pg',
@@ -353,7 +361,7 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
353361
admin.express.translatable(
354362
async (req: any, res: express.Response) => {
355363
const days = req.body.days || 7;
356-
const apartsByDays = await db.prepare(
364+
const apartsByDays = await admin.resource('aparts').dataConnector.client.prepare(
357365
`SELECT
358366
strftime('%Y-%m-%d', created_at) as day,
359367
COUNT(*) as count
@@ -367,7 +375,7 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
367375
const totalAparts = apartsByDays.reduce((acc: number, { count }: { count:number }) => acc + count, 0);
368376

369377
// add listed, unlisted, listedPrice, unlistedPrice
370-
const listedVsUnlistedByDays = await db.prepare(
378+
const listedVsUnlistedByDays = await admin.resource('aparts').dataConnector.client.prepare(
371379
`SELECT
372380
strftime('%Y-%m-%d', created_at) as day,
373381
SUM(listed) as listed,
@@ -381,7 +389,7 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
381389
`
382390
).all(days);
383391

384-
const apartsCountsByRooms = await db.prepare(
392+
const apartsCountsByRooms = await admin.resource('aparts').dataConnector.client.prepare(
385393
`SELECT
386394
number_of_rooms,
387395
COUNT(*) as count
@@ -391,7 +399,7 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
391399
`
392400
).all();
393401

394-
const topCountries = await db.prepare(
402+
const topCountries = await admin.resource('aparts').dataConnector.client.prepare(
395403
`SELECT
396404
country,
397405
COUNT(*) as count
@@ -402,14 +410,14 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
402410
`
403411
).all();
404412

405-
const totalSquare = await db.prepare(
413+
const totalSquare = await admin.resource('aparts').dataConnector.client.prepare(
406414
`SELECT
407415
SUM(square_meter) as totalSquare
408416
FROM apartments;
409417
`
410418
).get();
411419

412-
const listedVsUnlistedPriceByDays = await db.prepare(
420+
const listedVsUnlistedPriceByDays = await admin.resource('aparts').dataConnector.client.prepare(
413421
`SELECT
414422
strftime('%Y-%m-%d', created_at) as day,
415423
SUM(listed * price) as listedPrice,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "apartments" ADD COLUMN "apartment_source" TEXT;

dev-demo/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ model apartments {
3434
realtor_id String?
3535
user_id String?
3636
apartment_image String?
37+
apartment_source String?
3738
}
3839

3940
model audit_log {

0 commit comments

Comments
 (0)