Skip to content

Commit afe97c6

Browse files
committed
Merge branch 'next' of https://github.com/devforth/adminforth into feat/bulkActionComponent
2 parents 28d3d04 + ebd50b9 commit afe97c6

File tree

140 files changed

+12006
-2301
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+12006
-2301
lines changed

adapters/install-adapters.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/usr/bin/env bash
2-
ADAPTERS="adminforth-completion-adapter-open-ai-chat-gpt adminforth-email-adapter-aws-ses adminforth-email-adapter-mailgun adminforth-google-oauth-adapter adminforth-github-oauth-adapter adminforth-facebook-oauth-adapter adminforth-keycloak-oauth-adapter adminforth-microsoft-oauth-adapter adminforth-twitch-oauth-adapter adminforth-image-generation-adapter-openai adminforth-storage-adapter-amazon-s3 adminforth-storage-adapter-local"
2+
ADAPTERS="adminforth-completion-adapter-open-ai-chat-gpt adminforth-email-adapter-aws-ses \
3+
adminforth-email-adapter-mailgun adminforth-google-oauth-adapter adminforth-github-oauth-adapter \
4+
adminforth-facebook-oauth-adapter adminforth-keycloak-oauth-adapter adminforth-microsoft-oauth-adapter \
5+
adminforth-twitch-oauth-adapter adminforth-image-generation-adapter-openai adminforth-storage-adapter-amazon-s3 \
6+
adminforth-storage-adapter-local adminforth-image-vision-adapter-openai adminforth-key-value-adapter-ram \
7+
adminforth-login-captcha-adapter-cloudflare adminforth-login-captcha-adapter-recaptcha"
38

49
# for each
510
install_adapter() {

adminforth/auth.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,29 @@ class AdminForthAuth implements IAdminForthAuth {
9999
}
100100

101101
setCustomCookie({ response, payload }: {
102-
response: any, payload: {name: string, value: string, expiry: number, httpOnly: boolean}
102+
response: any, payload: { name: string, value: string, expiry: number | undefined, expirySeconds: number | undefined, httpOnly: boolean }
103103
}) {
104-
const {name, value, expiry, httpOnly} = payload;
104+
const {name, value, expiry, httpOnly, expirySeconds } = payload;
105+
106+
let expiryMs = 24 * 60 * 60 * 1000; // default 1 day
107+
if (expirySeconds !== undefined) {
108+
expiryMs = expirySeconds * 1000;
109+
} else if (expiry !== undefined) {
110+
console.warn('setCustomCookie: expiry(in ms) is deprecated, use expirySeconds instead (seconds), traceback:', new Error().stack);
111+
expiryMs = expiry;
112+
}
113+
105114
const brandSlug = this.adminforth.config.customization.brandNameSlug;
106115
response.setHeader('Set-Cookie', `adminforth_${brandSlug}_${name}=${value}; Path=${this.adminforth.config.baseUrl || '/'};${
107116
httpOnly ? ' HttpOnly;' : ''
108-
} SameSite=Strict; Expires=${new Date(Date.now() + expiry).toUTCString() } `);
117+
} SameSite=Strict; Expires=${new Date(Date.now() + expiryMs).toUTCString() } `);
118+
}
119+
120+
getCustomCookie({ cookies, name }: {
121+
cookies: {key: string, value: string}[], name: string
122+
}): string | null {
123+
const brandSlug = this.adminforth.config.customization.brandNameSlug;
124+
return cookies.find((cookie) => cookie.key === `adminforth_${brandSlug}_${name}`)?.value || null;
109125
}
110126

111127
issueJWT(payload: Object, type: string, expiresIn: string = '24h'): string {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Express } from "express";
2+
import { IAdminForth } from "adminforth";
3+
4+
export function initApi(app: Express, admin: IAdminForth) {
5+
app.get(`${admin.config.baseUrl}/api/hello/`,
6+
(req, res) => {
7+
res.json({ message: "Hello from AdminForth API!" });
8+
}
9+
);
10+
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import usersResource from "./resources/adminuser.js";
44
import { fileURLToPath } from 'url';
55
import path from 'path';
66
import { Filters } from 'adminforth';
7-
7+
import { initApi } from './api.js';
8+
89
const ADMIN_BASE_URL = '';
910

1011
export const admin = new AdminForth({
@@ -30,7 +31,8 @@ export const admin = new AdminForth({
3031
brandLogo: '@@/assets/logo.svg',
3132
datesFormat: 'DD MMM',
3233
timeFormat: 'HH:mm a',
33-
showBrandNameInSidebar: true,
34+
showBrandNameInSidebar: true,
35+
showBrandLogoInSidebar: true,
3436
emptyFieldPlaceholder: '-',
3537
styles: {
3638
colors: {
@@ -68,6 +70,8 @@ if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
6870
const app = express();
6971
app.use(express.json());
7072

73+
initApi(app, admin);
74+
7175
const port = 3500;
7276

7377
admin.bundleNow({ hotReload: process.env.NODE_ENV === 'development' }).then(() => {

adminforth/commands/createApp/utils.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ async function writeTemplateFiles(dirname, cwd, options) {
235235
dest: 'index.ts',
236236
data: { appName },
237237
},
238+
{
239+
src: 'api.ts.hbs',
240+
dest: 'api.ts',
241+
data: {},
242+
},
238243
{
239244
src: '.gitignore.hbs',
240245
dest: '.gitignore',

adminforth/commands/createCustomComponent/configLoader.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,20 @@ import fs from 'fs/promises';
22
import path from 'path';
33
import chalk from 'chalk';
44
import jiti from 'jiti';
5-
import dotenv from "dotenv";
5+
import dotenv, { config } from "dotenv";
66

77
dotenv.config({ path: '.env.local', override: true });
88
dotenv.config({ path: '.env', override: true });
99

10-
export async function loadAdminForthConfig() {
10+
export async function getAdminInstance() {
1111
const configFileName = 'index.ts';
1212
const configPath = path.resolve(process.cwd(), configFileName);
13-
1413
try {
1514
await fs.access(configPath);
1615
} catch (error) {
1716
console.error(chalk.red(`\nError: Configuration file not found at ${configPath}`));
1817
console.error(chalk.yellow(`Please ensure you are running this command from your project's root directory and the '${configFileName}' file exists.`));
19-
process.exit(1);
18+
return null;
2019
}
2120

2221
try {
@@ -29,8 +28,19 @@ export async function loadAdminForthConfig() {
2928
const configModule = _require(configPath);
3029

3130
const adminInstance = configModule.admin || configModule.default?.admin;
31+
return { adminInstance, configPath, configFileName };
32+
} catch (error) {
33+
console.error(chalk.red(`\nError loading or parsing configuration file: ${configPath}`));
34+
console.error(error);
35+
return null;
36+
}
37+
}
3238

39+
export async function loadAdminForthConfig() {
40+
41+
const { adminInstance, configPath, configFileName } = await getAdminInstance();
3342

43+
try {
3444
if (!adminInstance) {
3545
throw new Error(`Could not find 'admin' export in ${configFileName}. Please ensure your config file exports the AdminForth instance like: 'export const admin = new AdminForth({...});'`);
3646
}
@@ -53,7 +63,7 @@ export async function loadAdminForthConfig() {
5363
return config;
5464

5565
} catch (error) {
56-
console.error(chalk.red(`\nError loading or parsing configuration file: ${configPath}`));
66+
console.error(chalk.red(`\nError loading or parsing configuration file: ${configPath}, error: ${error}`));
5767
console.error(error);
5868
process.exit(1);
5969
}

adminforth/commands/createCustomComponent/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ async function handleCrudPageInjectionCreation(config, resources) {
189189
message: 'Where exactly do you want to inject the component?',
190190
choices: [
191191
{ name: '⬆️ Before Breadcrumbs', value: 'beforeBreadcrumbs' },
192+
{ name: '➡️ Before Action Buttons', value: 'beforeActionButtons' },
192193
{ name: '⬇️ After Breadcrumbs', value: 'afterBreadcrumbs' },
193194
{ name: '📄 After Page', value: 'bottom' },
194195
{ name: '⋯ threeDotsDropdownItems', value: 'threeDotsDropdownItems' },
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<template>
2+
<div class="flex items-center p-4 md:p-5 gap-2">
3+
<button
4+
type="button"
5+
@click="handleClick"
6+
class="text-white bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:bg-blue-500 dark:hover:bg-blue-600 dark:focus:ring-blue-800"
7+
>
8+
{{ '{{' }} $t('Example') {{ '}}' }}
9+
</button>
10+
</div>
11+
</template>
12+
13+
<script setup lang="ts">
14+
import { onMounted } from 'vue';
15+
import { useI18n } from 'vue-i18n';
16+
import adminforth from '@/adminforth';
17+
import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18+
19+
const { t } = useI18n();
20+
21+
const props = defineProps<{
22+
record: any
23+
resource: AdminForthResourceCommon
24+
adminUser: AdminUser
25+
meta?: any
26+
}>();
27+
28+
onMounted(() => {
29+
// Logic on mount if needed
30+
});
31+
32+
function handleClick() {
33+
adminforth.alert({
34+
message: t('Confirmed'),
35+
variant: 'success',
36+
});
37+
}
38+
</script>

adminforth/commands/createPlugin/templates/custom/tsconfig.json.hbs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
"baseUrl": ".", // This should point to your project root
44
"paths": {
55
"@/*": [
6-
// "node_modules/adminforth/dist/spa/src/*"
7-
"../../../spa/src/*"
6+
"../node_modules/adminforth/dist/spa/src/*"
87
],
98
"*": [
10-
// "node_modules/adminforth/dist/spa/node_modules/*"
11-
"../../../spa/node_modules/*"
9+
"../node_modules/adminforth/dist/spa/node_modules/*"
1210
],
1311
"@@/*": [
14-
// "node_modules/adminforth/dist/spa/src/*"
1512
"."
1613
]
1714
}

adminforth/commands/createPlugin/templates/package.json.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"types": "dist/index.d.ts",
66
"type": "module",
77
"scripts": {
8-
"build": "tsc && rsync -av --exclude 'node_modules' custom dist/ && npm version patch"
8+
"build": "tsc && rsync -av --exclude 'node_modules' custom dist/"
99
},
1010
"keywords": [],
1111
"author": "",

0 commit comments

Comments
 (0)