Skip to content

Commit 079b94c

Browse files
authored
Merge pull request #209 from devforth/next
Next
2 parents 1d1231a + e75d10b commit 079b94c

File tree

16 files changed

+131
-25
lines changed

16 files changed

+131
-25
lines changed

adminforth/documentation/docs/tutorial/001-gettingStarted.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,6 @@ nvm use 20
1919

2020
The recommended way to get started with AdminForth is via the **`create-app`** CLI, which scaffolds a basic fully functional back-office application. Apart boilerplate it creates one resource for users management.
2121

22-
First, create and enter a directory where you want your AdminForth project to live. For instance:
23-
24-
```bash
25-
mkdir myadmin
26-
cd myadmin
27-
```
28-
2922
You can provide options directorly:
3023

3124
```bash
@@ -38,6 +31,12 @@ Or omit them to be prompted interactively:
3831
npx adminforth create-app
3932
```
4033

34+
Once the project is created, navigate into its directory:
35+
36+
```bash
37+
cd myadmin # or any other name you provided
38+
```
39+
4140
CLI options:
4241

4342
* **`--app-name`** - name for your project. Used in `package.json`, `index.ts` branding, etc. Default value: **`adminforth-app`**.

adminforth/documentation/docs/tutorial/03-Customization/09-Actions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Return:
8585
- A string with an error message to explain why access was denied
8686

8787
Here is how it looks:
88-
![alt text](<Custom bulk actions.png>)
88+
![alt text](<Single record actions.png>)
8989

9090

9191
You might want to allow only certain users to perform your custom bulk action.
157 KB
Loading

adminforth/documentation/docs/tutorial/05-Plugins/01-AuditLog.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,15 @@ app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
165165
admin.express.authorize(
166166
async (req, res) => {
167167

168-
admin.getPluginByClassName<AuditLogPlugin>('AuditLogPlugin').logCustomAction(
169-
'aparts',
170-
null, // recordId can be null if not applicable
171-
'visitedDashboard',
172-
{ dashboard: 'main' },
173-
req.adminUser,
174-
req.headers //required if you want log client ip
175-
)
168+
admin.getPluginByClassName<AuditLogPlugin>('AuditLogPlugin').logCustomAction({
169+
resourceId: 'aparts',
170+
recordId: null, // recordId can be null if not applicable
171+
actionId: 'visitedDashboard', // any random string you want to useto identify this action
172+
oldData: null, // old data, can be null if not applicable
173+
data: { dashboard: 'main' }, // new data or any data you want to log
174+
user: req.adminUser,
175+
headers: req.headers //required if you want log client ip
176+
})
176177

177178
....
178179

adminforth/documentation/docs/tutorial/05-Plugins/10-i18n.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,63 @@ If you want to limit access to translations resource only to developers or trans
325325
326326
Please note that access to "Translate selected" bulk action which uses LLM AI translation adapter is determined by allowedActions.edit permission of resource.
327327
328+
## Proofreading checkboxes
329+
330+
You can enable didicated checkboxes for proofreading translations. This will allow proofreaders to check each translation and mark it "reviewed" or "not reviewed".
331+
332+
TO enable this options add TEXT column to the resource.
333+
334+
If using prisma, add something like this:
335+
336+
```ts title='./schema.prisma'
337+
model translations {
338+
...
339+
completedLangs String?
340+
//diff-add
341+
reviewed String?
342+
343+
// we need both indexes on en_string+category and separately on category
344+
@@index([en_string, category])
345+
@@index([category])
346+
@@index([completedLangs])
347+
}
348+
```
349+
350+
And add column to the resource:
351+
352+
```ts title='./resources/translations.ts'
353+
{
354+
...
355+
columns: [
356+
...
357+
{
358+
name: "reviewed",
359+
type: AdminForthDataTypes.JSON, // should be JSON type
360+
label: 'Reviewed',
361+
showIn: {
362+
all: false
363+
},
364+
},
365+
],
366+
}
367+
```
368+
369+
370+
Now just add `reviewedCheckboxesFieldName` to the plugin options:
371+
372+
```ts title='./resources/translations.ts'
373+
plugins: [
374+
new I18nPlugin({
375+
...
376+
reviewedCheckboxesFieldName: 'reviewed',
377+
}),
378+
],
379+
```
380+
This will add checkboxes to the translations resource:
381+
382+
![alt text](image-5.png)
383+
384+
328385
## Translations in custom APIs
329386
330387
Sometimes you need to return a translated error or success message from your API. You can use special `tr` function for this.
169 KB
Loading

adminforth/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import SQLiteConnector from './dataConnectors/sqlite.js';
66
import CodeInjector from './modules/codeInjector.js';
77
import ExpressServer from './servers/express.js';
88
// import FastifyServer from './servers/fastify.js';
9-
import { ADMINFORTH_VERSION, listify, suggestIfTypo, RateLimiter, getClientIp } from './modules/utils.js';
9+
import { ADMINFORTH_VERSION, listify, suggestIfTypo, RateLimiter, RAMLock, getClientIp } from './modules/utils.js';
1010

1111
import {
1212
type AdminForthConfig,
@@ -42,7 +42,7 @@ export * from './types/Common.js';
4242
export * from './types/Adapters.js';
4343
export { interpretResource };
4444
export { AdminForthPlugin };
45-
export { suggestIfTypo, RateLimiter, getClientIp };
45+
export { suggestIfTypo, RateLimiter, RAMLock, getClientIp };
4646

4747

4848
class AdminForth implements IAdminForth {
@@ -478,7 +478,6 @@ class AdminForth implements IAdminForth {
478478
{ resource, recordId, record, oldRecord, adminUser, extra }:
479479
{ resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
480480
): Promise<{ error?: string }> {
481-
482481
const err = this.validateRecordValues(resource, record);
483482
if (err) {
484483
return { error: err };

adminforth/modules/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,36 @@ export class RateLimiter {
455455
}
456456
}
457457

458+
}
459+
460+
export class RAMLock {
461+
private locks: Map<string, { locked: boolean; queue: Function[] }>;
462+
463+
constructor() {
464+
this.locks = new Map();
465+
}
466+
467+
_getLock(key) {
468+
if (!this.locks.has(key)) {
469+
this.locks.set(key, { locked: false, queue: [] });
470+
}
471+
return this.locks.get(key);
472+
}
473+
474+
async run(key, fn) {
475+
const lock = this._getLock(key);
476+
while (lock.locked) {
477+
await new Promise(resolve => lock.queue.push(resolve));
478+
}
479+
lock.locked = true;
480+
try {
481+
return await fn();
482+
} finally {
483+
lock.locked = false;
484+
if (lock.queue.length > 0) {
485+
const next = lock.queue.shift();
486+
next();
487+
}
488+
}
489+
}
458490
}

adminforth/spa/src/afcl/Checkbox.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
type="checkbox"
66
:checked="props.modelValue"
77
@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" />
8+
class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-lightPrimary cursor-pointer
9+
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" />
910
</div>
1011
<label :for="id" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">
1112
<slot></slot>

adminforth/spa/src/afcl/Input.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ const props = defineProps<{
3939
type: string,
4040
fullWidth: boolean,
4141
modelValue: string,
42-
suffix: string,
43-
prefix: string,
42+
suffix?: string,
43+
prefix?: string,
4444
readonly?: boolean,
4545
}>()
4646

0 commit comments

Comments
 (0)