2023-02-12 14:43:48 +08:00
import type { Field } from '@formily/core' ;
2023-01-04 19:27:37 +08:00
import { ISchema } from '@formily/react' ;
2023-02-28 17:55:58 +08:00
import { IField , interfacesProperties , useCollectionManager , useRecord } from '@nocobase/client' ;
2023-01-04 19:27:37 +08:00
import { cloneDeep } from 'lodash' ;
2023-02-28 17:55:58 +08:00
import { NAMESPACE } from './locale' ;
2023-01-04 19:27:37 +08:00
2023-02-12 14:43:48 +08:00
const { defaultProps } = interfacesProperties ;
const APPENDS = 'appends' ;
const TARGET_FIELD = 'targetField' ;
export const useTopRecord = ( ) = > {
let record = useRecord ( ) ;
while ( record && Object . keys ( record . __parent ) . length > 0 ) {
record = record . __parent ;
}
return record ;
} ;
const onTargetFieldChange = ( field : Field ) = > {
field . value ; // for watch
const targetField = field . query ( ` . ${ APPENDS } ` ) . take ( ) as Field | undefined ;
console . log ( field . path ) ;
if ( ! targetField ) return ;
! targetField . getState ( ) . disabled && targetField . setValue ( [ ] ) ;
} ;
2023-01-04 19:27:37 +08:00
2023-02-28 17:55:58 +08:00
function makeFieldsPathOptions ( fields , appends = [ ] ) {
const { getCollection } = useCollectionManager ( ) ;
const options = [ ] ;
2023-02-28 22:57:47 +08:00
fields . forEach ( ( field ) = > {
2023-02-28 17:55:58 +08:00
if ( [ 'belongsTo' , 'hasOne' , 'hasMany' , 'belongsToMany' ] . includes ( field . type ) ) {
2023-02-28 22:57:47 +08:00
const currentAppends = appends . filter ( ( key ) = > ` ${ key } . ` . startsWith ( ` ${ field . name } . ` ) ) ;
2023-02-28 17:55:58 +08:00
if ( currentAppends . length ) {
const nextCollection = getCollection ( field . target ) ;
const nextAppends = currentAppends
2023-02-28 22:57:47 +08:00
. filter ( ( key ) = > key !== field . name )
. map ( ( key ) = > key . replace ( ` ${ field . name } . ` , '' ) )
. filter ( ( key ) = > key ) ;
2023-02-28 17:55:58 +08:00
options . push ( {
label : field.uiSchema?.title ? ? field . name ,
value : field.name ,
children : makeFieldsPathOptions ( nextCollection . fields , nextAppends ) ,
} ) ;
}
} else {
options . push ( {
label : field.uiSchema?.title ? ? field . name ,
value : field.name ,
} ) ;
}
} ) ;
return options ;
}
2023-01-04 19:27:37 +08:00
2023-02-28 17:55:58 +08:00
const recordPickerViewer = {
type : 'void' ,
title : ` {{t('View record')}} ` ,
'x-component' : 'RecordPicker.Viewer' ,
'x-component-props' : {
className : 'nb-action-popup' ,
} ,
properties : {
tabs : {
type : 'void' ,
'x-component' : 'Tabs' ,
'x-component-props' : { } ,
// 'x-initializer': 'TabPaneInitializers',
properties : {
tab1 : {
type : 'void' ,
title : ` {{t('Detail')}} ` ,
'x-component' : 'Tabs.TabPane' ,
'x-designer' : 'Tabs.Designer' ,
'x-component-props' : { } ,
properties : {
grid : {
type : 'void' ,
'x-component' : 'Grid' ,
'x-initializer' : 'SnapshotBlockInitializers' ,
properties : { } ,
2023-01-04 19:27:37 +08:00
} ,
} ,
} ,
} ,
} ,
2023-02-28 17:55:58 +08:00
} ,
} ;
2023-01-04 19:27:37 +08:00
2023-02-28 17:55:58 +08:00
export const snapshot : IField = {
name : 'snapshot' ,
type : 'object' ,
group : 'advanced' ,
title : ` {{t('Snapshot', {ns: ' ${ NAMESPACE } '})}} ` ,
2023-02-28 22:57:47 +08:00
description : ` {{t('When adding a new record, create a snapshot for its relational record and save in the current record. The snapshot is not updated when the record is subsequently updated.', {ns: ' ${ NAMESPACE } '})}} ` ,
2023-02-28 17:55:58 +08:00
default : {
type : 'snapshot' ,
// name,
uiSchema : {
// title,
'x-component' : 'SnapshotRecordPicker' ,
'x-component-props' : {
multiple : true ,
fieldNames : {
label : 'id' ,
value : 'id' ,
2023-01-04 19:27:37 +08:00
} ,
} ,
} ,
2023-02-28 17:55:58 +08:00
} ,
schemaInitialize ( schema : ISchema , { field , readPretty , action , block } ) {
schema [ 'properties' ] = {
viewer : cloneDeep ( recordPickerViewer ) ,
} ;
} ,
initialize : ( values : any ) = > { } ,
usePathOptions ( field ) {
const { appends = [ ] , targetCollection } = field ;
const { getCollection } = useCollectionManager ( ) ;
const { fields } = getCollection ( targetCollection ) ;
const result = makeFieldsPathOptions ( fields , appends ) ;
return [
{
label : ` {{t('Snapshot data', { ns: ' ${ NAMESPACE } ' })}} ` ,
value : 'data' ,
children : result ,
2023-02-28 22:57:47 +08:00
} ,
2023-02-28 17:55:58 +08:00
] ;
} ,
properties : {
. . . defaultProps ,
[ TARGET_FIELD ] : {
type : 'string' ,
2023-02-28 22:57:47 +08:00
title : ` {{t('The association field to snapshot', {ns: ' ${ NAMESPACE } '})}} ` ,
2023-02-28 17:55:58 +08:00
required : true ,
'x-decorator' : 'FormItem' ,
'x-component' : 'SnapshotOwnerCollectionFieldsSelect' ,
'x-disabled' : '{{ !createOnly || isOverride }}' ,
'x-reactions' : [
{
target : APPENDS ,
when : '{{$self.value != undefined}}' ,
fulfill : {
state : {
visible : true ,
2023-02-12 14:43:48 +08:00
} ,
} ,
2023-02-28 17:55:58 +08:00
otherwise : {
state : {
visible : false ,
2023-02-12 14:43:48 +08:00
} ,
} ,
2023-02-28 17:55:58 +08:00
} ,
] ,
2023-01-04 19:27:37 +08:00
} ,
2023-02-28 17:55:58 +08:00
[ APPENDS ] : {
type : 'string' ,
2023-02-28 22:57:47 +08:00
title : ` {{t("Snapshot the snapshot's association fields", {ns: " ${ NAMESPACE } "})}} ` ,
2023-02-28 17:55:58 +08:00
'x-decorator' : 'FormItem' ,
'x-component' : 'AppendsTreeSelect' ,
'x-reactions' : [
{
dependencies : [ TARGET_FIELD ] ,
when : '{{$deps[0]}}' ,
fulfill : {
run : '{{$self.setValue($self.value)}}' ,
} ,
} ,
] ,
} ,
} ,
2023-01-04 19:27:37 +08:00
} ;