Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
import { AdminJSOptions, Assets } from '../../../adminjs-options.interface'
import { Paths } from '../../../frontend/store/store'
let globalAny: any = {}
try {
globalAny = window
} catch (error) {
if (error.message !== 'window is not defined') {
throw error
}
}
/**
* Base Params for a any function
* @alias ActionParams
* @memberof ViewHelpers
*/
export type ActionParams = {
/**
* Unique Resource ID
*/
resourceId: string;
/**
* Action name
*/
actionName: string;
/**
* Optional query string: ?....
*/
search? : string;
}
/**
* Params for a record action
* @alias RecordActionParams
* @extends ActionParams
* @memberof ViewHelpers
*/
export type RecordActionParams = ActionParams & {
/**
* Record ID
*/
recordId: string;
}
/**
* Params for a bulk action
* @alias BulkActionParams
* @extends ActionParams
* @memberof ViewHelpers
*/
export type BulkActionParams = ActionParams & {
/**
* Array of Records ID
*/
recordIds?: Array<string>;
}
/**
* Params for a resource action
* @alias ResourceActionParams
* @extends ActionParams
* @memberof ViewHelpers
*/
export type ResourceActionParams = ActionParams
const runDate = new Date()
/**
* Collection of helper methods available in the views
*/
export class ViewHelpers {
public options: Paths
constructor({ options }: { options?: AdminJSOptions } = {}) {
let opts: Paths = ViewHelpers.getPaths(options)
opts = opts || {
rootPath: '/admin',
}
// when ViewHelpers are used on the frontend, paths are taken from global Redux State
this.options = opts
}
static getPaths(options?: AdminJSOptions): Paths {
return options || (globalAny.REDUX_STATE?.paths)
}
/**
* To each related path adds rootPath passed by the user, as well as a query string
* @private
* @param {Array<string>} [paths] list of parts of the url
* @return {string} path
* @return {query} [search=''] query string which can be fetch
* from `location.search`
*/
urlBuilder(paths: Array<string> = [], search = ''): string {
const separator = '/'
const replace = new RegExp(`${separator}{1,}`, 'g')
let { rootPath } = this.options
if (!rootPath.startsWith(separator)) { rootPath = `${separator}${rootPath}` }
const parts = [rootPath, ...paths]
return `${parts.join(separator).replace(replace, separator)}${search}`
}
/**
* Returns login URL
* @return {string}
*/
loginUrl(): string {
return this.options.loginPath
}
/**
* Returns logout URL
* @return {string}
*/
logoutUrl(): string {
return this.options.logoutPath
}
/**
* Returns URL for the dashboard
* @return {string}
*/
dashboardUrl(): string {
return this.options.rootPath
}
/**
* Returns URL for given page name
* @param {string} pageName page name which is a unique key specified in
* {@link AdminJSOptions}
* @return {string}
*/
pageUrl(pageName: string): string {
return this.urlBuilder(['pages', pageName])
}
/**
* Returns url for a `edit` action in given Resource. Uses {@link recordActionUrl}
*
* @param {string} resourceId id to the resource
* @param {string} recordId id to the record
* @param {string} [search] optional query string
*/
editUrl(resourceId: string, recordId: string, search?: string): string {
return this.recordActionUrl({ resourceId, recordId, actionName: 'edit', search })
}
/**
* Returns url for a `show` action in given Resource. Uses {@link recordActionUrl}
*
* @param {string} resourceId id to the resource
* @param {string} recordId id to the record
* @param {string} [search] optional query string
*/
showUrl(resourceId: string, recordId: string, search?: string): string {
return this.recordActionUrl({ resourceId, recordId, actionName: 'show', search })
}
/**
* Returns url for a `delete` action in given Resource. Uses {@link recordActionUrl}
*
* @param {string} resourceId id to the resource
* @param {string} recordId id to the record
* @param {string} [search] optional query string
*/
deleteUrl(resourceId: string, recordId: string, search?: string): string {
return this.recordActionUrl({ resourceId, recordId, actionName: 'delete', search })
}
/**
* Returns url for a `new` action in given Resource. Uses {@link resourceActionUrl}
*
* @param {string} resourceId id to the resource
* @param {string} [search] optional query string
*/
newUrl(resourceId: string, search?: string): string {
return this.resourceActionUrl({ resourceId, actionName: 'new', search })
}
/**
* Returns url for a `list` action in given Resource. Uses {@link resourceActionUrl}
*
* @param {string} resourceId id to the resource
* @param {string} [search] optional query string
*/
listUrl(resourceId: string, search?: string): string {
return this.resourceActionUrl({ resourceId, actionName: 'list', search })
}
/**
* Returns url for a `bulkDelete` action in given Resource. Uses {@link bulkActionUrl}
*
* @param {string} resourceId id to the resource
* @param {Array<string>} recordIds separated by comma records
* @param {string} [search] optional query string
*/
bulkDeleteUrl(resourceId: string, recordIds: Array<string>, search?: string): string {
return this.bulkActionUrl({ resourceId, recordIds, actionName: 'bulkDelete', search })
}
/**
* Returns resourceAction url
*
* @param {ResourceActionParams} options
* @param {string} options.resourceId
* @param {string} options.actionName
* @param {string} [options.search] optional query string
*
* @return {string}
*/
resourceActionUrl({ resourceId, actionName, search }: ResourceActionParams): string {
return this.urlBuilder(['resources', resourceId, 'actions', actionName], search)
}
resourceUrl({ resourceId, search }: Omit<ResourceActionParams, 'actionName'>): string {
return this.urlBuilder(['resources', resourceId], search)
}
/**
* Returns recordAction url
*
* @param {RecordActionParams} options
* @param {string} options.resourceId
* @param {string} options.recordId
* @param {string} options.actionName
*
* @return {string}
*/
recordActionUrl({ resourceId, recordId, actionName, search }: RecordActionParams): string {
return this.urlBuilder(['resources', resourceId, 'records', recordId, actionName], search)
}
/**
* Returns bulkAction url
*
* @param {BulkActionParams} options
* @param {string} options.resourceId
* @param {Array<string>} [options.recordIds]
* @param {string} options.actionName
*
* @return {string}
*/
bulkActionUrl({ resourceId, recordIds, actionName, search }: BulkActionParams): string {
const url = this.urlBuilder([
'resources', resourceId, 'bulk', actionName,
])
if (recordIds && recordIds.length) {
const query = new URLSearchParams(search)
query.set('recordIds', recordIds.join(','))
return `${url}?${query.toString()}`
}
return `${url}${search || ''}`
}
/**
* Returns absolute path to a given asset.
* @private
*
* @param {string} asset
* @param {Assets | undefined} assetsConfig
* @return {string}
*/
assetPath(asset: string, assetsConfig?: Assets): string {
if (this.options.assetsCDN) {
const pathname = assetsConfig?.coreScripts?.[asset] ?? asset
const url = new URL(pathname, this.options.assetsCDN).href
// adding timestamp to the href invalidates the CDN cache
return `${url}?date=${runDate.getTime()}`
}
return this.urlBuilder(['frontend', 'assets', asset])
}
}
export default ViewHelpers