Skip to content

Commit 68e414d

Browse files
committed
Merge branch 'next' of github.com:devforth/adminforth into next
2 parents 7b8f26f + 021b2f1 commit 68e414d

File tree

5 files changed

+44
-27
lines changed

5 files changed

+44
-27
lines changed

adminforth/documentation/docs/tutorial/03-Customization/01-branding.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,8 @@ const admin = new AdminForth({
3131
title: "myadmin",
3232
//diff-add
3333
title: 'My App Admin', // used to set HTML title tag
34-
//diff-remove
35-
brandLogo: '@@/assets/logo.svg',
36-
//diff-add
37-
brandLogo: '@@/logo.svg',
38-
//diff-remove
34+
brandLogo: '@@/assets/logo.svg', // replace with your images in custom/assets directory
3935
favicon: '@@/assets/favicon.png',
40-
//diff-add
41-
favicon: '@@/favicon.png',
42-
//diff-add
4336
},
4437
...
4538
});
@@ -97,7 +90,7 @@ const admin = new AdminForth({
9790
//diff-remove
9891
sidebar: { main: '#f9fafb', text: '#213045' },
9992
//diff-add
100-
sidebar: {main:'#571e58', text:'white'},
93+
sidebar: { main:'#571e58', text: 'white'},
10194
},
10295
}
10396
}

adminforth/modules/configValidator.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -330,23 +330,38 @@ export default class ConfigValidator implements IConfigValidator {
330330
return showInTransformedToObject as ShowIn;
331331
}
332332

333-
validateFieldGroups(fieldGroups: {
334-
groupName: string;
335-
columns: string[];
336-
}[], resourceColumns: string[]): void {
337-
if (!fieldGroups) return;
333+
validateFieldGroups(fieldGroups: { groupName: string; columns: string[] }[], allColumnsList: string[]): string[] {
334+
if (!fieldGroups) return allColumnsList;
335+
336+
const columnPositions = new Map<string, number>();
337+
let position = 0;
338338

339339
fieldGroups.forEach((group) => {
340340
group.columns.forEach((col) => {
341-
if (!resourceColumns.includes(col)) {
342-
const similar = suggestIfTypo(resourceColumns, col);
341+
if (!allColumnsList.includes(col)) {
342+
const similar = suggestIfTypo(allColumnsList, col);
343343
throw new Error(
344-
`Group '${group.groupName}' has an unknown column '${col}'. ${similar ? `Did you mean '${similar}'?` : ''
344+
`Group '${group.groupName}' has an unknown column '${col}'. ${
345+
similar ? `Did you mean '${similar}'?` : ''
345346
}`
346347
);
347348
}
349+
if (!columnPositions.has(col)) {
350+
columnPositions.set(col, position++);
351+
}
348352
});
349353
});
354+
355+
allColumnsList.forEach((col) => {
356+
if (!columnPositions.has(col)) {
357+
columnPositions.set(col, position++);
358+
}
359+
});
360+
return allColumnsList.sort((a, b) => {
361+
const posA = columnPositions.get(a);
362+
const posB = columnPositions.get(b);
363+
return posA - posB;
364+
});
350365
}
351366

352367
validateAndNormalizeCustomActions(resInput: AdminForthResourceInput, res: Partial<AdminForthResource>, errors: string[]): any[] {
@@ -422,7 +437,7 @@ export default class ConfigValidator implements IConfigValidator {
422437
res.columns = [];
423438
}
424439
res.columns = resInput.columns.map((inCol: AdminForthResourceColumnInput, inColIndex) => {
425-
const col: Partial<AdminForthResourceColumn> = { ...inCol, showIn: undefined, required: undefined, editingNote: undefined };
440+
const col: Partial<AdminForthResourceColumn> = { ...inCol, showIn: undefined, editingNote: undefined };
426441

427442
// check for duplicate column names
428443
if (resInput.columns.findIndex((c) => c.name === col.name) !== inColIndex) {
@@ -476,9 +491,6 @@ export default class ConfigValidator implements IConfigValidator {
476491
}
477492
}
478493

479-
// force required to be object
480-
col.required = typeof inCol.required === 'boolean' ? { create: inCol.required, edit: inCol.required } : inCol.required;
481-
482494

483495
// same for editingNote
484496
if (inCol.editingNote && !((typeof inCol.editingNote === 'string') || (typeof inCol.editingNote === 'object'))) {
@@ -706,10 +718,11 @@ export default class ConfigValidator implements IConfigValidator {
706718
options.actions = this.validateAndNormalizeCustomActions(resInput, res, errors);
707719

708720
const allColumnsList = res.columns.map((col) => col.name);
709-
this.validateFieldGroups(options.fieldGroups, allColumnsList);
710-
this.validateFieldGroups(options.showFieldGroups, allColumnsList);
711-
this.validateFieldGroups(options.createFieldGroups, allColumnsList);
712-
this.validateFieldGroups(options.editFieldGroups, allColumnsList);
721+
const sortedColumns = this.validateFieldGroups(options.fieldGroups, allColumnsList);
722+
723+
res.columns = res.columns.sort((a, b) => {
724+
return sortedColumns.indexOf(a.name) - sortedColumns.indexOf(b.name);
725+
});
713726

714727
// if pageInjection is a string, make array with one element. Also check file exists
715728
const possibleInjections = ['beforeBreadcrumbs', 'afterBreadcrumbs', 'bottom', 'threeDotsDropdownItems', 'customActionIcons'];

adminforth/spa/src/components/ColumnValueInput.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex">
2+
<div class="flex" :class="{ 'opacity-50' : column.editReadonly && source === 'edit' }">
33
<component
44
v-if="column?.components?.[props.source]?.file"
55
:is="getCustomComponent(column.components[props.source])"
@@ -48,6 +48,8 @@
4848
step="1"
4949
class="w-40"
5050
placeholder="0"
51+
:min="![undefined, null].includes(column.minValue) ? column.minValue : ''"
52+
:max="![undefined, null].includes(column.maxValue) ? column.maxValue : ''"
5153
:prefix="column.inputPrefix"
5254
:suffix="column.inputSuffix"
5355
:readonly="column.editReadonly && source === 'edit'"
@@ -70,6 +72,8 @@
7072
step="0.1"
7173
class="w-40"
7274
placeholder="0.0"
75+
:min="![undefined, null].includes(column.minValue) ? column.minValue : ''"
76+
:max="![undefined, null].includes(column.maxValue) ? column.maxValue : ''"
7377
:prefix="column.inputPrefix"
7478
:suffix="column.inputSuffix"
7579
:modelValue="value"

adminforth/spa/src/components/ResourceForm.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,12 @@ onMounted(() => {
245245
currentValues.value[column.name] = [];
246246
} else {
247247
// else copy array to prevent mutation
248-
currentValues.value[column.name] = [...currentValues.value[column.name]];
248+
if (Array.isArray(currentValues.value[column.name])) {
249+
currentValues.value[column.name] = [...currentValues.value[column.name]];
250+
} else {
251+
// fallback for old data
252+
currentValues.value[column.name] = [`${currentValues.value[column.name]}`];
253+
}
249254
}
250255
} else if (currentValues.value[column.name]) {
251256
currentValues.value[column.name] = JSON.stringify(currentValues.value[column.name], null, 2);

dev-demo/resources/apartments.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ export default {
190190
showIn: {create: true, edit: true, filter: true, show: true},
191191
allowMinMaxQuery: true, // use better experience for filtering e.g. date range, set it only if you have index on this column or if there will be low number of rows
192192
editingNote: "Price is in USD", // you can appear note on editing or creating page
193+
editReadonly: true, // you can set field to be readonly on edit page
194+
193195
},
194196
{
195197
name: "square_meter",

0 commit comments

Comments
 (0)