Skip to content

Commit

Permalink
Merge pull request #887 from SoftwareBrothers/beta
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
dziraf committed Jul 20, 2021
2 parents f95e525 + 6baca86 commit 1380a2e
Show file tree
Hide file tree
Showing 18 changed files with 76 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "adminjs",
"version": "5.0.1",
"version": "5.1.0-beta.1",
"description": "Admin panel for apps written in node.js",
"main": "index.js",
"types": "index.d.ts",
Expand Down
Expand Up @@ -44,7 +44,7 @@ context('resources/Taggables/actions/new', () => {
cy.get('button[type="submit"]').click()

cy.location('pathname').should('eq', '/admin/resources/Taggables').then(function () {
cy.get(`[data-id="${this.data.id}"] [data-property-name="tags"]`).should('have.text', 'length: 0')
cy.get(`[data-id="${this.data.id}"] [data-property-name="tags"]`).should('have.text', 'Length: 0')
})
})

Expand Down
3 changes: 2 additions & 1 deletion src/adminjs.ts
Expand Up @@ -9,7 +9,7 @@ import BaseDatabase from './backend/adapters/database/base-database'
import ConfigurationError from './backend/utils/errors/configuration-error'
import ResourcesFactory from './backend/utils/resources-factory/resources-factory'
import userComponentsBundler from './backend/bundler/user-components-bundler'
import { RecordActionResponse, Action } from './backend/actions/action.interface'
import { RecordActionResponse, Action, BulkActionResponse } from './backend/actions/action.interface'
import { DEFAULT_PATHS } from './constants'
import { ACTIONS } from './backend/actions'

Expand Down Expand Up @@ -37,6 +37,7 @@ type ActionsMap = {
show: Action<RecordActionResponse>;
edit: Action<RecordActionResponse>;
delete: Action<RecordActionResponse>;
bulkDelete: Action<BulkActionResponse>;
new: Action<RecordActionResponse>;
list: Action<ListActionResponse>;
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/decorators/property/property-decorator.ts
Expand Up @@ -144,7 +144,7 @@ class PropertyDecorator {
*
* @returns {Array<{value: string, label: string}>}
*/
availableValues(): null | Array<{value: string; label: string}> {
availableValues(): null | Array<{value: string | number; label: string}> {
if (this.options.availableValues) {
return this.options.availableValues
}
Expand Down
Expand Up @@ -62,7 +62,7 @@ export default interface PropertyOptions {
* in the UI you will see select box instead of the input
*/
availableValues?: Array<{
value: string;
value: string | number;
label: string;
}>;

Expand Down
2 changes: 1 addition & 1 deletion src/backend/decorators/resource/resource-decorator.spec.ts
Expand Up @@ -60,7 +60,7 @@ describe('ResourceDecorator', function () {
describe('#getNavigation', function () {
it('returns custom name with icon when options were specified', function () {
const options = {
navigation: { name: 'someName', icon: 'someIcon' },
navigation: { name: 'someName', icon: 'someIcon', show: true },
}
expect(
new ResourceDecorator({ ...args, options }).getNavigation(),
Expand Down
16 changes: 10 additions & 6 deletions src/backend/decorators/resource/resource-options.interface.ts
Expand Up @@ -72,20 +72,24 @@ export interface ResourceOptions {
*/
href?: HrefFunction | string;
/**
* Navigation option saying under which resource should be nested in sidebar.
* Navigation option saying under which menu this resource should be nested in sidebar.
* Default to the database name.
*
* You have couple of options:
* - when you give both name and icon - your resource will be nested under this menu.
* - when you set it to null - resource will be top level, but without the icon
* - finally you can set the icon but leave name as `null`. In such case resource will be
* top level and it will have an icon.
* - when you set both navigation.name and navigation.icon this resource will be nested under
* this menu.
* - when you set navigation.name or navigation to a string this resource will be nested under
* this menu and the icon will come from the database type
* - when you set navigation.icon but leave navigation.name as `null` this resource will be top
* level and it will have an icon.
* - when you set navigation to null this resource will be top level, but without the icon
* - when you set navigation to false this resource will be hidden in the navigation
* @new In version 3.3
*/
navigation?: {
name?: string | null;
icon?: string;
} | string | null;
} | string | boolean | null;


/**
Expand Down
14 changes: 14 additions & 0 deletions src/backend/decorators/resource/utils/get-navigation.spec.ts
Expand Up @@ -26,6 +26,7 @@ describe('.getNavigation', () => {
expect(getNavigation(resourceOptions, defaultDatabase)).to.deep.eq({
icon: mappedIcon,
name: databaseName,
show: true,
})
})

Expand All @@ -35,13 +36,24 @@ describe('.getNavigation', () => {
expect(getNavigation(resourceOptions, defaultDatabase)).to.be.null
})

it('returns show false when options are set to false', () => {
resourceOptions.navigation = false

expect(getNavigation(resourceOptions, defaultDatabase)).to.deep.eq({
name: null,
icon: '',
show: false,
})
})

it('returns parent with a default icon when options was set as a string', () => {
const parentName = 'my navigation name'
resourceOptions.navigation = parentName

expect(getNavigation(resourceOptions, defaultDatabase)).to.deep.eq({
icon: mappedIcon,
name: parentName,
show: true,
})
})

Expand All @@ -52,6 +64,7 @@ describe('.getNavigation', () => {
expect(getNavigation(resourceOptions, defaultDatabase)).to.deep.eq({
icon,
name: null,
show: true,
})
})

Expand All @@ -62,6 +75,7 @@ describe('.getNavigation', () => {
expect(getNavigation(resourceOptions, defaultDatabase)).to.deep.eq({
icon,
name: null,
show: true,
})
})
})
12 changes: 11 additions & 1 deletion src/backend/decorators/resource/utils/get-navigation.ts
Expand Up @@ -35,19 +35,29 @@ export const getNavigation = (
? options.navigation
: options.parent

if (navigationOption === null) {
if (navigationOption === null || navigationOption === true) {
return null
}

if (navigationOption === false) {
return {
name: null,
icon: '',
show: false,
}
}

if (navigationOption === undefined || typeof navigationOption === 'string') {
return {
name: navigationOption || database.databaseName(),
icon: getIcon(database.databaseType()),
show: true,
}
}
const { name, icon } = navigationOption
return {
name: name || null,
icon: icon || getIcon(database.databaseType()),
show: true,
}
}
15 changes: 15 additions & 0 deletions src/backend/utils/build-feature/build-feature.spec.ts
Expand Up @@ -82,4 +82,19 @@ describe('mergeResourceOptions', function () {
},
})
})

it('merges falsey options', function () {
const existingOptions = {
navigation: {
name: 'db',
},
}
const newOptions = {
navigation: false,
}

expect(mergeResourceOptions(existingOptions, newOptions)).to.deep.eq({
navigation: false,
})
})
})
8 changes: 4 additions & 4 deletions src/backend/utils/build-feature/build-feature.ts
Expand Up @@ -70,16 +70,16 @@ const mergeResourceOptions = (
const options = { ...oldOptions }

basicOptions.forEach((propName: string) => {
if (newOptions[propName]) {
if (propName in newOptions) {
options[propName] = newOptions[propName]
}
})

listOptions.forEach((propName: string) => {
if (newOptions[propName]) {
if (propName in newOptions) {
const mergedOptions = [
...(oldOptions && oldOptions[propName] ? oldOptions[propName] : []),
...(newOptions && newOptions[propName] ? newOptions[propName] : []),
...(oldOptions && (propName in oldOptions) ? oldOptions[propName] : []),
...(newOptions && (propName in newOptions) ? newOptions[propName] : []),
]

options[propName] = uniq(mergedOptions)
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/components/actions/new.tsx
Expand Up @@ -37,7 +37,7 @@ const New: FC<ActionProps> = (props) => {
history.push(appendForceRefresh(response.data.redirectUrl))
}
// if record has id === has been created
if (response.data.record.id) {
if (response.data.record.id && !Object.keys(response.data.record.errors).length) {
handleChange({ params: {}, populated: {}, errors: {} } as RecordJSON)
}
})
Expand Down
6 changes: 4 additions & 2 deletions src/frontend/components/property-type/array/list.tsx
@@ -1,6 +1,7 @@
import React from 'react'
import { flat } from '../../../../utils'

import { useTranslation } from '../../../hooks/use-translation'
import { flat } from '../../../../utils'
import { RecordJSON, ResourceJSON, PropertyJSON } from '../../../interfaces'
import { ShowPropertyProps } from '../base-property-props'

Expand All @@ -13,9 +14,10 @@ interface Props {
const List: React.FC<ShowPropertyProps> = (props) => {
const { property, record } = props
const values = flat.get(record.params, property.path) || []
const { translateProperty } = useTranslation()

return (
<span>{`length: ${values.length}`}</span>
<span>{`${translateProperty('length')}: ${values.length}`}</span>
)
}

Expand Down
1 change: 1 addition & 0 deletions src/frontend/components/spec/resource-json.factory.ts
Expand Up @@ -10,6 +10,7 @@ factory.define<ResourceJSON>('ResourceJSON', Object, {
navigation: {
name: 'someName',
icon: 'someIcon',
show: true,
},
actions: [],
resourceActions: [],
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/hooks/use-navigation-resources.ts
Expand Up @@ -42,7 +42,8 @@ export function useNavigationResources(

// grouping resources into parents
const map = resources
.filter(res => res.href) // first filter out resource which are not visible
// first filter out resources which are not visible
.filter(res => res.href && res.navigation?.show !== false)
.reduce((memo, resource) => {
// in case resource has the same name as parent we namespace it wit "resource-""
const key = resource.navigation?.name || ['resource', resource.name].join('-')
Expand Down
Expand Up @@ -26,7 +26,7 @@ export interface PropertyJSON {
/**
* If property has restricted number of values
*/
availableValues: Array<{label: string; value: string}> | null;
availableValues: Array<{label: string; value: string | number}> | null;
/**
* Property uniq name
*/
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/interfaces/resource-json.interface.ts
Expand Up @@ -32,6 +32,10 @@ export interface ResourceJSON {
* Parent icon
*/
icon: string;
/**
* Visibility
*/
show: boolean;
} | null;

/**
Expand Down
3 changes: 2 additions & 1 deletion src/locale/en.ts
Expand Up @@ -18,6 +18,7 @@ const translations = {
confirmRemovalMany: 'Confirm the removal of {{count}} record',
confirmRemovalMany_plural: 'Confirm the removal of {{count}} records',
logout: 'Log out',
login: 'Log in',
seeTheDocumentation: 'See: <1>the documentation</1>',
createFirstRecord: 'Create First Record',
},
Expand All @@ -31,7 +32,7 @@ const translations = {
loginWelcome: 'Welcome',
},
properties: {

length: 'Length',
},
resources: {

Expand Down

0 comments on commit 1380a2e

Please sign in to comment.