Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c537cb6934 | ||
|
|
9cb3c7e67a | ||
|
|
4e1d0ef1a2 | ||
|
|
ed48fd96e7 | ||
|
|
71abe38520 | ||
|
|
984dc3cf6a | ||
|
|
8b128d7646 |
@@ -583,7 +583,6 @@ type ViewField {
|
||||
workspaceId: UUID!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
isActive: Boolean!
|
||||
deletedAt: DateTime
|
||||
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
|
||||
}
|
||||
@@ -692,7 +691,6 @@ type ViewFieldGroup {
|
||||
workspaceId: UUID!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
isActive: Boolean!
|
||||
deletedAt: DateTime
|
||||
viewFields: [ViewField!]!
|
||||
isOverridden: Boolean! @deprecated(reason: "isOverridden is deprecated")
|
||||
@@ -901,7 +899,6 @@ type PageLayoutWidget {
|
||||
conditionalAvailabilityExpression: String
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
isActive: Boolean!
|
||||
deletedAt: DateTime
|
||||
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
|
||||
}
|
||||
@@ -1237,7 +1234,6 @@ type PageLayoutTab {
|
||||
layoutMode: PageLayoutTabLayoutMode
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
isActive: Boolean!
|
||||
deletedAt: DateTime
|
||||
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
|
||||
}
|
||||
@@ -2197,18 +2193,30 @@ type DeletedWorkspaceMember {
|
||||
userWorkspaceId: UUID
|
||||
}
|
||||
|
||||
type Relation {
|
||||
type: RelationType!
|
||||
sourceObjectMetadata: Object!
|
||||
targetObjectMetadata: Object!
|
||||
sourceFieldMetadata: Field!
|
||||
targetFieldMetadata: Field!
|
||||
type BillingEntitlement {
|
||||
key: BillingEntitlementKey!
|
||||
value: Boolean!
|
||||
}
|
||||
|
||||
"""Relation type"""
|
||||
enum RelationType {
|
||||
ONE_TO_MANY
|
||||
MANY_TO_ONE
|
||||
enum BillingEntitlementKey {
|
||||
SSO
|
||||
CUSTOM_DOMAIN
|
||||
RLS
|
||||
AUDIT_LOGS
|
||||
}
|
||||
|
||||
type DomainRecord {
|
||||
validationType: String!
|
||||
type: String!
|
||||
status: String!
|
||||
key: String!
|
||||
value: String!
|
||||
}
|
||||
|
||||
type DomainValidRecords {
|
||||
id: UUID!
|
||||
domain: String!
|
||||
records: [DomainRecord!]!
|
||||
}
|
||||
|
||||
type IndexEdge {
|
||||
@@ -2310,6 +2318,25 @@ type ObjectFieldsConnection {
|
||||
edges: [FieldEdge!]!
|
||||
}
|
||||
|
||||
type UpsertRowLevelPermissionPredicatesResult {
|
||||
predicates: [RowLevelPermissionPredicate!]!
|
||||
predicateGroups: [RowLevelPermissionPredicateGroup!]!
|
||||
}
|
||||
|
||||
type Relation {
|
||||
type: RelationType!
|
||||
sourceObjectMetadata: Object!
|
||||
targetObjectMetadata: Object!
|
||||
sourceFieldMetadata: Field!
|
||||
targetFieldMetadata: Field!
|
||||
}
|
||||
|
||||
"""Relation type"""
|
||||
enum RelationType {
|
||||
ONE_TO_MANY
|
||||
MANY_TO_ONE
|
||||
}
|
||||
|
||||
type FieldConnection {
|
||||
"""Paging information"""
|
||||
pageInfo: PageInfo!
|
||||
@@ -2318,37 +2345,6 @@ type FieldConnection {
|
||||
edges: [FieldEdge!]!
|
||||
}
|
||||
|
||||
type BillingEntitlement {
|
||||
key: BillingEntitlementKey!
|
||||
value: Boolean!
|
||||
}
|
||||
|
||||
enum BillingEntitlementKey {
|
||||
SSO
|
||||
CUSTOM_DOMAIN
|
||||
RLS
|
||||
AUDIT_LOGS
|
||||
}
|
||||
|
||||
type DomainRecord {
|
||||
validationType: String!
|
||||
type: String!
|
||||
status: String!
|
||||
key: String!
|
||||
value: String!
|
||||
}
|
||||
|
||||
type DomainValidRecords {
|
||||
id: UUID!
|
||||
domain: String!
|
||||
records: [DomainRecord!]!
|
||||
}
|
||||
|
||||
type UpsertRowLevelPermissionPredicatesResult {
|
||||
predicates: [RowLevelPermissionPredicate!]!
|
||||
predicateGroups: [RowLevelPermissionPredicateGroup!]!
|
||||
}
|
||||
|
||||
type AuthToken {
|
||||
token: String!
|
||||
expiresAt: DateTime!
|
||||
@@ -2584,6 +2580,7 @@ type Location {
|
||||
}
|
||||
|
||||
type PlaceDetailsResult {
|
||||
street: String
|
||||
state: String
|
||||
postcode: String
|
||||
city: String
|
||||
|
||||
@@ -415,7 +415,6 @@ export interface ViewField {
|
||||
workspaceId: Scalars['UUID']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
isActive: Scalars['Boolean']
|
||||
deletedAt?: Scalars['DateTime']
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: Scalars['Boolean']
|
||||
@@ -493,7 +492,6 @@ export interface ViewFieldGroup {
|
||||
workspaceId: Scalars['UUID']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
isActive: Scalars['Boolean']
|
||||
deletedAt?: Scalars['DateTime']
|
||||
viewFields: ViewField[]
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
@@ -676,7 +674,6 @@ export interface PageLayoutWidget {
|
||||
conditionalAvailabilityExpression?: Scalars['String']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
isActive: Scalars['Boolean']
|
||||
deletedAt?: Scalars['DateTime']
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: Scalars['Boolean']
|
||||
@@ -962,7 +959,6 @@ export interface PageLayoutTab {
|
||||
layoutMode?: PageLayoutTabLayoutMode
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
isActive: Scalars['Boolean']
|
||||
deletedAt?: Scalars['DateTime']
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: Scalars['Boolean']
|
||||
@@ -1883,18 +1879,29 @@ export interface DeletedWorkspaceMember {
|
||||
__typename: 'DeletedWorkspaceMember'
|
||||
}
|
||||
|
||||
export interface Relation {
|
||||
type: RelationType
|
||||
sourceObjectMetadata: Object
|
||||
targetObjectMetadata: Object
|
||||
sourceFieldMetadata: Field
|
||||
targetFieldMetadata: Field
|
||||
__typename: 'Relation'
|
||||
export interface BillingEntitlement {
|
||||
key: BillingEntitlementKey
|
||||
value: Scalars['Boolean']
|
||||
__typename: 'BillingEntitlement'
|
||||
}
|
||||
|
||||
export type BillingEntitlementKey = 'SSO' | 'CUSTOM_DOMAIN' | 'RLS' | 'AUDIT_LOGS'
|
||||
|
||||
/** Relation type */
|
||||
export type RelationType = 'ONE_TO_MANY' | 'MANY_TO_ONE'
|
||||
export interface DomainRecord {
|
||||
validationType: Scalars['String']
|
||||
type: Scalars['String']
|
||||
status: Scalars['String']
|
||||
key: Scalars['String']
|
||||
value: Scalars['String']
|
||||
__typename: 'DomainRecord'
|
||||
}
|
||||
|
||||
export interface DomainValidRecords {
|
||||
id: Scalars['UUID']
|
||||
domain: Scalars['String']
|
||||
records: DomainRecord[]
|
||||
__typename: 'DomainValidRecords'
|
||||
}
|
||||
|
||||
export interface IndexEdge {
|
||||
/** The node containing the Index */
|
||||
@@ -1994,6 +2001,25 @@ export interface ObjectFieldsConnection {
|
||||
__typename: 'ObjectFieldsConnection'
|
||||
}
|
||||
|
||||
export interface UpsertRowLevelPermissionPredicatesResult {
|
||||
predicates: RowLevelPermissionPredicate[]
|
||||
predicateGroups: RowLevelPermissionPredicateGroup[]
|
||||
__typename: 'UpsertRowLevelPermissionPredicatesResult'
|
||||
}
|
||||
|
||||
export interface Relation {
|
||||
type: RelationType
|
||||
sourceObjectMetadata: Object
|
||||
targetObjectMetadata: Object
|
||||
sourceFieldMetadata: Field
|
||||
targetFieldMetadata: Field
|
||||
__typename: 'Relation'
|
||||
}
|
||||
|
||||
|
||||
/** Relation type */
|
||||
export type RelationType = 'ONE_TO_MANY' | 'MANY_TO_ONE'
|
||||
|
||||
export interface FieldConnection {
|
||||
/** Paging information */
|
||||
pageInfo: PageInfo
|
||||
@@ -2002,36 +2028,6 @@ export interface FieldConnection {
|
||||
__typename: 'FieldConnection'
|
||||
}
|
||||
|
||||
export interface BillingEntitlement {
|
||||
key: BillingEntitlementKey
|
||||
value: Scalars['Boolean']
|
||||
__typename: 'BillingEntitlement'
|
||||
}
|
||||
|
||||
export type BillingEntitlementKey = 'SSO' | 'CUSTOM_DOMAIN' | 'RLS' | 'AUDIT_LOGS'
|
||||
|
||||
export interface DomainRecord {
|
||||
validationType: Scalars['String']
|
||||
type: Scalars['String']
|
||||
status: Scalars['String']
|
||||
key: Scalars['String']
|
||||
value: Scalars['String']
|
||||
__typename: 'DomainRecord'
|
||||
}
|
||||
|
||||
export interface DomainValidRecords {
|
||||
id: Scalars['UUID']
|
||||
domain: Scalars['String']
|
||||
records: DomainRecord[]
|
||||
__typename: 'DomainValidRecords'
|
||||
}
|
||||
|
||||
export interface UpsertRowLevelPermissionPredicatesResult {
|
||||
predicates: RowLevelPermissionPredicate[]
|
||||
predicateGroups: RowLevelPermissionPredicateGroup[]
|
||||
__typename: 'UpsertRowLevelPermissionPredicatesResult'
|
||||
}
|
||||
|
||||
export interface AuthToken {
|
||||
token: Scalars['String']
|
||||
expiresAt: Scalars['DateTime']
|
||||
@@ -2297,6 +2293,7 @@ export interface Location {
|
||||
}
|
||||
|
||||
export interface PlaceDetailsResult {
|
||||
street?: Scalars['String']
|
||||
state?: Scalars['String']
|
||||
postcode?: Scalars['String']
|
||||
city?: Scalars['String']
|
||||
@@ -3635,7 +3632,6 @@ export interface ViewFieldGenqlSelection{
|
||||
workspaceId?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
isActive?: boolean | number
|
||||
deletedAt?: boolean | number
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: boolean | number
|
||||
@@ -3710,7 +3706,6 @@ export interface ViewFieldGroupGenqlSelection{
|
||||
workspaceId?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
isActive?: boolean | number
|
||||
deletedAt?: boolean | number
|
||||
viewFields?: ViewFieldGenqlSelection
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
@@ -3885,7 +3880,6 @@ export interface PageLayoutWidgetGenqlSelection{
|
||||
conditionalAvailabilityExpression?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
isActive?: boolean | number
|
||||
deletedAt?: boolean | number
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: boolean | number
|
||||
@@ -4198,7 +4192,6 @@ export interface PageLayoutTabGenqlSelection{
|
||||
layoutMode?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
isActive?: boolean | number
|
||||
deletedAt?: boolean | number
|
||||
/** @deprecated isOverridden is deprecated */
|
||||
isOverridden?: boolean | number
|
||||
@@ -5157,12 +5150,27 @@ export interface DeletedWorkspaceMemberGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface RelationGenqlSelection{
|
||||
export interface BillingEntitlementGenqlSelection{
|
||||
key?: boolean | number
|
||||
value?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface DomainRecordGenqlSelection{
|
||||
validationType?: boolean | number
|
||||
type?: boolean | number
|
||||
sourceObjectMetadata?: ObjectGenqlSelection
|
||||
targetObjectMetadata?: ObjectGenqlSelection
|
||||
sourceFieldMetadata?: FieldGenqlSelection
|
||||
targetFieldMetadata?: FieldGenqlSelection
|
||||
status?: boolean | number
|
||||
key?: boolean | number
|
||||
value?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface DomainValidRecordsGenqlSelection{
|
||||
id?: boolean | number
|
||||
domain?: boolean | number
|
||||
records?: DomainRecordGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
@@ -5277,6 +5285,23 @@ export interface ObjectFieldsConnectionGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{
|
||||
predicates?: RowLevelPermissionPredicateGenqlSelection
|
||||
predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface RelationGenqlSelection{
|
||||
type?: boolean | number
|
||||
sourceObjectMetadata?: ObjectGenqlSelection
|
||||
targetObjectMetadata?: ObjectGenqlSelection
|
||||
sourceFieldMetadata?: FieldGenqlSelection
|
||||
targetFieldMetadata?: FieldGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface FieldConnectionGenqlSelection{
|
||||
/** Paging information */
|
||||
pageInfo?: PageInfoGenqlSelection
|
||||
@@ -5286,38 +5311,6 @@ export interface FieldConnectionGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface BillingEntitlementGenqlSelection{
|
||||
key?: boolean | number
|
||||
value?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface DomainRecordGenqlSelection{
|
||||
validationType?: boolean | number
|
||||
type?: boolean | number
|
||||
status?: boolean | number
|
||||
key?: boolean | number
|
||||
value?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface DomainValidRecordsGenqlSelection{
|
||||
id?: boolean | number
|
||||
domain?: boolean | number
|
||||
records?: DomainRecordGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{
|
||||
predicates?: RowLevelPermissionPredicateGenqlSelection
|
||||
predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface AuthTokenGenqlSelection{
|
||||
token?: boolean | number
|
||||
expiresAt?: boolean | number
|
||||
@@ -5616,6 +5609,7 @@ export interface LocationGenqlSelection{
|
||||
}
|
||||
|
||||
export interface PlaceDetailsResultGenqlSelection{
|
||||
street?: boolean | number
|
||||
state?: boolean | number
|
||||
postcode?: boolean | number
|
||||
city?: boolean | number
|
||||
@@ -8240,10 +8234,26 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const Relation_possibleTypes: string[] = ['Relation']
|
||||
export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"')
|
||||
return Relation_possibleTypes.includes(obj.__typename)
|
||||
const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement']
|
||||
export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"')
|
||||
return BillingEntitlement_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const DomainRecord_possibleTypes: string[] = ['DomainRecord']
|
||||
export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"')
|
||||
return DomainRecord_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords']
|
||||
export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"')
|
||||
return DomainValidRecords_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
@@ -8344,38 +8354,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const FieldConnection_possibleTypes: string[] = ['FieldConnection']
|
||||
export const isFieldConnection = (obj?: { __typename?: any } | null): obj is FieldConnection => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConnection"')
|
||||
return FieldConnection_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement']
|
||||
export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"')
|
||||
return BillingEntitlement_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const DomainRecord_possibleTypes: string[] = ['DomainRecord']
|
||||
export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"')
|
||||
return DomainRecord_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords']
|
||||
export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"')
|
||||
return DomainValidRecords_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const UpsertRowLevelPermissionPredicatesResult_possibleTypes: string[] = ['UpsertRowLevelPermissionPredicatesResult']
|
||||
export const isUpsertRowLevelPermissionPredicatesResult = (obj?: { __typename?: any } | null): obj is UpsertRowLevelPermissionPredicatesResult => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isUpsertRowLevelPermissionPredicatesResult"')
|
||||
@@ -8384,6 +8362,22 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const Relation_possibleTypes: string[] = ['Relation']
|
||||
export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"')
|
||||
return Relation_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const FieldConnection_possibleTypes: string[] = ['FieldConnection']
|
||||
export const isFieldConnection = (obj?: { __typename?: any } | null): obj is FieldConnection => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConnection"')
|
||||
return FieldConnection_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const AuthToken_possibleTypes: string[] = ['AuthToken']
|
||||
export const isAuthToken = (obj?: { __typename?: any } | null): obj is AuthToken => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isAuthToken"')
|
||||
@@ -9584,11 +9578,6 @@ export const enumQueueMetricsTimeRange = {
|
||||
OneHour: 'OneHour' as const
|
||||
}
|
||||
|
||||
export const enumRelationType = {
|
||||
ONE_TO_MANY: 'ONE_TO_MANY' as const,
|
||||
MANY_TO_ONE: 'MANY_TO_ONE' as const
|
||||
}
|
||||
|
||||
export const enumBillingEntitlementKey = {
|
||||
SSO: 'SSO' as const,
|
||||
CUSTOM_DOMAIN: 'CUSTOM_DOMAIN' as const,
|
||||
@@ -9596,6 +9585,11 @@ export const enumBillingEntitlementKey = {
|
||||
AUDIT_LOGS: 'AUDIT_LOGS' as const
|
||||
}
|
||||
|
||||
export const enumRelationType = {
|
||||
ONE_TO_MANY: 'ONE_TO_MANY' as const,
|
||||
MANY_TO_ONE: 'MANY_TO_ONE' as const
|
||||
}
|
||||
|
||||
export const enumEmailingDomainDriver = {
|
||||
AWS_SES: 'AWS_SES' as const
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export default {
|
||||
209,
|
||||
221,
|
||||
238,
|
||||
253,
|
||||
255,
|
||||
292,
|
||||
293,
|
||||
303,
|
||||
@@ -789,10 +789,10 @@ export default {
|
||||
3
|
||||
],
|
||||
"relation": [
|
||||
237
|
||||
254
|
||||
],
|
||||
"morphRelations": [
|
||||
237
|
||||
254
|
||||
],
|
||||
"object": [
|
||||
46
|
||||
@@ -851,7 +851,7 @@ export default {
|
||||
36
|
||||
],
|
||||
"objectMetadata": [
|
||||
245,
|
||||
247,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -864,7 +864,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"indexFieldMetadatas": [
|
||||
243,
|
||||
245,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -1109,7 +1109,7 @@ export default {
|
||||
37
|
||||
],
|
||||
"fields": [
|
||||
250,
|
||||
252,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -1122,7 +1122,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"indexMetadatas": [
|
||||
248,
|
||||
250,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -1283,9 +1283,6 @@ export default {
|
||||
"updatedAt": [
|
||||
4
|
||||
],
|
||||
"isActive": [
|
||||
6
|
||||
],
|
||||
"deletedAt": [
|
||||
4
|
||||
],
|
||||
@@ -1459,9 +1456,6 @@ export default {
|
||||
"updatedAt": [
|
||||
4
|
||||
],
|
||||
"isActive": [
|
||||
6
|
||||
],
|
||||
"deletedAt": [
|
||||
4
|
||||
],
|
||||
@@ -1709,7 +1703,7 @@ export default {
|
||||
131
|
||||
],
|
||||
"billingEntitlements": [
|
||||
252
|
||||
237
|
||||
],
|
||||
"hasValidEnterpriseKey": [
|
||||
6
|
||||
@@ -1909,9 +1903,6 @@ export default {
|
||||
"updatedAt": [
|
||||
4
|
||||
],
|
||||
"isActive": [
|
||||
6
|
||||
],
|
||||
"deletedAt": [
|
||||
4
|
||||
],
|
||||
@@ -2570,9 +2561,6 @@ export default {
|
||||
"updatedAt": [
|
||||
4
|
||||
],
|
||||
"isActive": [
|
||||
6
|
||||
],
|
||||
"deletedAt": [
|
||||
4
|
||||
],
|
||||
@@ -4431,179 +4419,9 @@ export default {
|
||||
1
|
||||
]
|
||||
},
|
||||
"Relation": {
|
||||
"type": [
|
||||
238
|
||||
],
|
||||
"sourceObjectMetadata": [
|
||||
46
|
||||
],
|
||||
"targetObjectMetadata": [
|
||||
46
|
||||
],
|
||||
"sourceFieldMetadata": [
|
||||
34
|
||||
],
|
||||
"targetFieldMetadata": [
|
||||
34
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"RelationType": {},
|
||||
"IndexEdge": {
|
||||
"node": [
|
||||
37
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"PageInfo": {
|
||||
"hasNextPage": [
|
||||
6
|
||||
],
|
||||
"hasPreviousPage": [
|
||||
6
|
||||
],
|
||||
"startCursor": [
|
||||
40
|
||||
],
|
||||
"endCursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
239
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexFieldEdge": {
|
||||
"node": [
|
||||
36
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexIndexFieldMetadatasConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
242
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectEdge": {
|
||||
"node": [
|
||||
46
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexObjectMetadataConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
244
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectRecordCount": {
|
||||
"objectNamePlural": [
|
||||
1
|
||||
],
|
||||
"totalCount": [
|
||||
21
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
244
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectIndexMetadatasConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
239
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"FieldEdge": {
|
||||
"node": [
|
||||
34
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectFieldsConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
249
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"FieldConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
],
|
||||
"edges": [
|
||||
249
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"BillingEntitlement": {
|
||||
"key": [
|
||||
253
|
||||
238
|
||||
],
|
||||
"value": [
|
||||
6
|
||||
@@ -4641,7 +4459,145 @@ export default {
|
||||
1
|
||||
],
|
||||
"records": [
|
||||
254
|
||||
239
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexEdge": {
|
||||
"node": [
|
||||
37
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"PageInfo": {
|
||||
"hasNextPage": [
|
||||
6
|
||||
],
|
||||
"hasPreviousPage": [
|
||||
6
|
||||
],
|
||||
"startCursor": [
|
||||
40
|
||||
],
|
||||
"endCursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
241
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexFieldEdge": {
|
||||
"node": [
|
||||
36
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexIndexFieldMetadatasConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
244
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectEdge": {
|
||||
"node": [
|
||||
46
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"IndexObjectMetadataConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
246
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectRecordCount": {
|
||||
"objectNamePlural": [
|
||||
1
|
||||
],
|
||||
"totalCount": [
|
||||
21
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
246
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectIndexMetadatasConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
241
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"FieldEdge": {
|
||||
"node": [
|
||||
34
|
||||
],
|
||||
"cursor": [
|
||||
40
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"ObjectFieldsConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
251
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
@@ -4658,6 +4614,38 @@ export default {
|
||||
1
|
||||
]
|
||||
},
|
||||
"Relation": {
|
||||
"type": [
|
||||
255
|
||||
],
|
||||
"sourceObjectMetadata": [
|
||||
46
|
||||
],
|
||||
"targetObjectMetadata": [
|
||||
46
|
||||
],
|
||||
"sourceFieldMetadata": [
|
||||
34
|
||||
],
|
||||
"targetFieldMetadata": [
|
||||
34
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"RelationType": {},
|
||||
"FieldConnection": {
|
||||
"pageInfo": [
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
251
|
||||
],
|
||||
"__typename": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"AuthToken": {
|
||||
"token": [
|
||||
1
|
||||
@@ -5170,6 +5158,9 @@ export default {
|
||||
]
|
||||
},
|
||||
"PlaceDetailsResult": {
|
||||
"street": [
|
||||
1
|
||||
],
|
||||
"state": [
|
||||
1
|
||||
],
|
||||
@@ -5987,7 +5978,7 @@ export default {
|
||||
},
|
||||
"AgentChatThreadConnection": {
|
||||
"pageInfo": [
|
||||
240
|
||||
242
|
||||
],
|
||||
"edges": [
|
||||
335
|
||||
@@ -6594,7 +6585,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"objectRecordCounts": [
|
||||
246
|
||||
248
|
||||
],
|
||||
"object": [
|
||||
46,
|
||||
@@ -6606,7 +6597,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
247,
|
||||
249,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -6628,7 +6619,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"indexMetadatas": [
|
||||
241,
|
||||
243,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -6677,7 +6668,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"fields": [
|
||||
251,
|
||||
256,
|
||||
{
|
||||
"paging": [
|
||||
39,
|
||||
@@ -8352,7 +8343,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"upsertRowLevelPermissionPredicates": [
|
||||
256,
|
||||
253,
|
||||
{
|
||||
"input": [
|
||||
456,
|
||||
@@ -9094,7 +9085,7 @@ export default {
|
||||
66
|
||||
],
|
||||
"checkCustomDomainValidRecords": [
|
||||
255
|
||||
240
|
||||
],
|
||||
"createOIDCIdentityProvider": [
|
||||
232,
|
||||
@@ -9427,7 +9418,7 @@ export default {
|
||||
}
|
||||
],
|
||||
"checkPublicDomainValidRecords": [
|
||||
255,
|
||||
240,
|
||||
{
|
||||
"domain": [
|
||||
1,
|
||||
|
||||
@@ -87,7 +87,7 @@ npm’ye yayımlamak, uygulamanızın Twenty pazaryerinde keşfedilebilir olmas
|
||||
### Gereksinimler
|
||||
|
||||
* Bir [npm](https://www.npmjs.com) hesabı
|
||||
* `package.json` içindeki `keywords` dizinizdeki `twenty-app` anahtar sözcüğü (elle ekleyin — varsayılan olarak `create-twenty-app` şablonunda yer almaz)
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (add it manually — it is not included by default in the `create-twenty-app` template)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
-1
@@ -14,7 +14,6 @@ export const PAGE_LAYOUT_TAB_FRAGMENT = gql`
|
||||
...PageLayoutWidgetFragment
|
||||
}
|
||||
pageLayoutId
|
||||
isActive
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
|
||||
+3
-1
@@ -132,18 +132,20 @@ describe('geo-map GraphQL queries', () => {
|
||||
queryDefinition.selectionSet.selections[0].selectionSet;
|
||||
const fields = selectionSet.selections.map((s: any) => s.name.value);
|
||||
|
||||
expect(fields).toContain('street');
|
||||
expect(fields).toContain('state');
|
||||
expect(fields).toContain('postcode');
|
||||
expect(fields).toContain('city');
|
||||
expect(fields).toContain('country');
|
||||
expect(fields).toContain('location');
|
||||
expect(fields).toHaveLength(5);
|
||||
expect(fields).toHaveLength(6);
|
||||
});
|
||||
|
||||
it('should match the expected query string', () => {
|
||||
const expectedQuery = gql`
|
||||
query GetAddressDetails($placeId: String!, $token: String!) {
|
||||
getAddressDetails(placeId: $placeId, token: $token) {
|
||||
street
|
||||
state
|
||||
postcode
|
||||
city
|
||||
|
||||
@@ -22,6 +22,7 @@ export const GET_AUTOCOMPLETE_QUERY = gql`
|
||||
export const GET_PLACE_DETAILS_QUERY = gql`
|
||||
query GetAddressDetails($placeId: String!, $token: String!) {
|
||||
getAddressDetails(placeId: $placeId, token: $token) {
|
||||
street
|
||||
state
|
||||
postcode
|
||||
city
|
||||
|
||||
@@ -13,6 +13,7 @@ export type PlaceAutocompleteResult = {
|
||||
};
|
||||
|
||||
export type PlaceDetailsResult = {
|
||||
street?: string;
|
||||
state?: string;
|
||||
postcode?: string;
|
||||
city?: string;
|
||||
|
||||
@@ -79,9 +79,7 @@ export const splitViewWithRelated = (
|
||||
const { viewFields: _viewFields, ...viewFieldGroupProperties } =
|
||||
viewFieldGroup;
|
||||
|
||||
flatViewFieldGroups.push({
|
||||
...viewFieldGroupProperties,
|
||||
});
|
||||
flatViewFieldGroups.push(viewFieldGroupProperties);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@ import { RecordFieldComponentInstanceContext } from '@/object-record/record-fiel
|
||||
import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useContext } from 'react';
|
||||
import { castAsNumberOrNull } from '~/utils/cast-as-number-or-null';
|
||||
|
||||
export const AddressFieldInput = () => {
|
||||
const { draftValue, setDraftValue, fieldDefinition } = useAddressField();
|
||||
@@ -25,8 +26,8 @@ export const AddressFieldInput = () => {
|
||||
addressState: newAddress?.addressState ?? null,
|
||||
addressCountry: newAddress?.addressCountry ?? null,
|
||||
addressPostcode: newAddress?.addressPostcode ?? null,
|
||||
addressLat: newAddress?.addressLat ?? null,
|
||||
addressLng: newAddress?.addressLng ?? null,
|
||||
addressLat: castAsNumberOrNull(newAddress?.addressLat),
|
||||
addressLng: castAsNumberOrNull(newAddress?.addressLng),
|
||||
};
|
||||
};
|
||||
const settings = fieldDefinition.metadata.settings;
|
||||
|
||||
@@ -58,7 +58,6 @@ const StyledContainer = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: ${TAB_LIST_HEIGHT};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
position: relative;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
|
||||
+26
-19
@@ -28,6 +28,7 @@ import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { SidePanelPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
@@ -46,6 +47,10 @@ const StyledTabsAndDashboardContainer = styled.div`
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const StyledPageLayoutTabListContainer = styled.div`
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledScrollWrapperContainer = styled.div`
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
@@ -163,25 +168,27 @@ export const PageLayoutTabsRenderer = () => {
|
||||
}
|
||||
/>
|
||||
{(sortedTabs.length > 1 || isPageLayoutInEditMode) && (
|
||||
<PageLayoutTabList
|
||||
tabs={sortedTabs}
|
||||
behaveAsLinks={!isInSidePanel && !isPageLayoutInEditMode}
|
||||
isInSidePanel={isInSidePanel}
|
||||
componentInstanceId={tabListInstanceId}
|
||||
onAddTab={handleAddTab}
|
||||
isReorderEnabled={canEnableTabEditing}
|
||||
onReorder={
|
||||
canEnableTabEditing
|
||||
? (result, provided) =>
|
||||
reorderRecordPageTabs(
|
||||
result,
|
||||
provided,
|
||||
isDefined(pinnedLeftTab),
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
pageLayoutType={currentPageLayout.type}
|
||||
/>
|
||||
<StyledPageLayoutTabListContainer>
|
||||
<PageLayoutTabList
|
||||
tabs={sortedTabs}
|
||||
behaveAsLinks={!isInSidePanel && !isPageLayoutInEditMode}
|
||||
isInSidePanel={isInSidePanel}
|
||||
componentInstanceId={tabListInstanceId}
|
||||
onAddTab={handleAddTab}
|
||||
isReorderEnabled={canEnableTabEditing}
|
||||
onReorder={
|
||||
canEnableTabEditing
|
||||
? (result, provided) =>
|
||||
reorderRecordPageTabs(
|
||||
result,
|
||||
provided,
|
||||
isDefined(pinnedLeftTab),
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
pageLayoutType={currentPageLayout.type}
|
||||
/>
|
||||
</StyledPageLayoutTabListContainer>
|
||||
)}
|
||||
|
||||
<StyledScrollWrapperContainer>
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ export const PageLayoutVerticalListEditor = ({
|
||||
<StyledVerticalListContainer
|
||||
ref={provided.innerRef}
|
||||
variant={variant}
|
||||
shouldUseWhiteBackground={!isInPinnedTab || isMobile}
|
||||
shouldUseWhiteBackground={isMobile || isInSidePanel}
|
||||
// oxlint-disable-next-line react/jsx-props-no-spreading
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ export const PageLayoutVerticalListViewer = ({
|
||||
return (
|
||||
<StyledVerticalListContainer
|
||||
variant={variant}
|
||||
shouldUseWhiteBackground={!isInPinnedTab || isMobile}
|
||||
shouldUseWhiteBackground={isMobile || isInSidePanel}
|
||||
>
|
||||
{widgets.map((widget) => (
|
||||
<div key={widget.id}>
|
||||
|
||||
-5
@@ -64,7 +64,6 @@ const mixedGraphsPageLayoutMocks = {
|
||||
tabs: [
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
id: 'mixed-tab',
|
||||
title: 'Mixed Graphs',
|
||||
position: 0,
|
||||
@@ -75,7 +74,6 @@ const mixedGraphsPageLayoutMocks = {
|
||||
widgets: [
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'number-widget',
|
||||
pageLayoutTabId: 'mixed-tab',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -100,7 +98,6 @@ const mixedGraphsPageLayoutMocks = {
|
||||
} satisfies PageLayoutWidget,
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'gauge-widget',
|
||||
pageLayoutTabId: 'mixed-tab',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -126,7 +123,6 @@ const mixedGraphsPageLayoutMocks = {
|
||||
} satisfies PageLayoutWidget,
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'pie-widget',
|
||||
pageLayoutTabId: 'mixed-tab',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -153,7 +149,6 @@ const mixedGraphsPageLayoutMocks = {
|
||||
} satisfies PageLayoutWidget,
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'bar-widget',
|
||||
pageLayoutTabId: 'mixed-tab',
|
||||
type: WidgetType.GRAPH,
|
||||
|
||||
-4
@@ -23,7 +23,6 @@ const StyledContainer = styled.div`
|
||||
const createInitialTabs = (): PageLayoutTab[] => [
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: 'overview',
|
||||
title: 'Overview',
|
||||
@@ -37,7 +36,6 @@ const createInitialTabs = (): PageLayoutTab[] => [
|
||||
},
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: 'revenue',
|
||||
title: 'Revenue',
|
||||
@@ -50,7 +48,6 @@ const createInitialTabs = (): PageLayoutTab[] => [
|
||||
},
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: 'forecasts',
|
||||
title: 'Forecasts',
|
||||
@@ -80,7 +77,6 @@ const PageLayoutTabListPlayground = ({
|
||||
...prev,
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: `new-tab-${nextIndex}`,
|
||||
title: `New Tab ${nextIndex}`,
|
||||
|
||||
-14
@@ -21,7 +21,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -61,7 +59,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -74,7 +71,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -101,7 +97,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-tasks',
|
||||
isActive: true,
|
||||
title: 'Tasks',
|
||||
icon: 'IconCheckbox',
|
||||
position: 300,
|
||||
@@ -114,7 +109,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-tasks',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-tasks',
|
||||
title: 'Tasks',
|
||||
type: WidgetType.TASKS,
|
||||
@@ -141,7 +135,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-notes',
|
||||
isActive: true,
|
||||
title: 'Notes',
|
||||
icon: 'IconNotes',
|
||||
position: 400,
|
||||
@@ -154,7 +147,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-notes',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-notes',
|
||||
title: 'Notes',
|
||||
type: WidgetType.NOTES,
|
||||
@@ -181,7 +173,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 500,
|
||||
@@ -194,7 +185,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
@@ -221,7 +211,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-emails',
|
||||
isActive: true,
|
||||
title: 'Emails',
|
||||
icon: 'IconMail',
|
||||
position: 600,
|
||||
@@ -234,7 +223,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-emails',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-emails',
|
||||
title: 'Emails',
|
||||
type: WidgetType.EMAILS,
|
||||
@@ -261,7 +249,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'company-tab-calendar',
|
||||
isActive: true,
|
||||
title: 'Calendar',
|
||||
icon: 'IconCalendarEvent',
|
||||
position: 700,
|
||||
@@ -274,7 +261,6 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'company-widget-calendar',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'company-tab-calendar',
|
||||
title: 'Calendar',
|
||||
type: WidgetType.CALENDAR,
|
||||
|
||||
-2
@@ -21,7 +21,6 @@ export const DEFAULT_MESSAGE_THREAD_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'message-thread-tab-home',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_MESSAGE_THREAD_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'message-thread-widget-email-thread',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'message-thread-tab-home',
|
||||
title: 'Thread',
|
||||
type: WidgetType.EMAIL_THREAD,
|
||||
|
||||
@@ -21,7 +21,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'note-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'note-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'note-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -61,7 +59,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'note-widget-note',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'note-tab-fields',
|
||||
title: 'Note',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
@@ -95,7 +92,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'note-tab-note',
|
||||
isActive: true,
|
||||
title: 'Note',
|
||||
icon: 'IconNotes',
|
||||
position: 150,
|
||||
@@ -108,7 +104,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'note-widget-note',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'note-tab-note',
|
||||
title: 'Note',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
@@ -142,7 +137,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'note-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -155,7 +149,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'note-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'note-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -182,7 +175,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'note-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 300,
|
||||
@@ -195,7 +187,6 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'note-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'note-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
|
||||
-14
@@ -21,7 +21,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -61,7 +59,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -74,7 +71,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -101,7 +97,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-tasks',
|
||||
isActive: true,
|
||||
title: 'Tasks',
|
||||
icon: 'IconCheckbox',
|
||||
position: 300,
|
||||
@@ -114,7 +109,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-tasks',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-tasks',
|
||||
title: 'Tasks',
|
||||
type: WidgetType.TASKS,
|
||||
@@ -141,7 +135,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-notes',
|
||||
isActive: true,
|
||||
title: 'Notes',
|
||||
icon: 'IconNotes',
|
||||
position: 400,
|
||||
@@ -154,7 +147,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-notes',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-notes',
|
||||
title: 'Notes',
|
||||
type: WidgetType.NOTES,
|
||||
@@ -181,7 +173,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 500,
|
||||
@@ -194,7 +185,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
@@ -221,7 +211,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-emails',
|
||||
isActive: true,
|
||||
title: 'Emails',
|
||||
icon: 'IconMail',
|
||||
position: 600,
|
||||
@@ -234,7 +223,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-emails',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-emails',
|
||||
title: 'Emails',
|
||||
type: WidgetType.EMAILS,
|
||||
@@ -261,7 +249,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'opportunity-tab-calendar',
|
||||
isActive: true,
|
||||
title: 'Calendar',
|
||||
icon: 'IconCalendarEvent',
|
||||
position: 700,
|
||||
@@ -274,7 +261,6 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'opportunity-widget-calendar',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'opportunity-tab-calendar',
|
||||
title: 'Calendar',
|
||||
type: WidgetType.CALENDAR,
|
||||
|
||||
-14
@@ -21,7 +21,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -61,7 +59,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -74,7 +71,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -101,7 +97,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-tasks',
|
||||
isActive: true,
|
||||
title: 'Tasks',
|
||||
icon: 'IconCheckbox',
|
||||
position: 300,
|
||||
@@ -114,7 +109,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-tasks',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-tasks',
|
||||
title: 'Tasks',
|
||||
type: WidgetType.TASKS,
|
||||
@@ -141,7 +135,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-notes',
|
||||
isActive: true,
|
||||
title: 'Notes',
|
||||
icon: 'IconNotes',
|
||||
position: 400,
|
||||
@@ -154,7 +147,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-notes',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-notes',
|
||||
title: 'Notes',
|
||||
type: WidgetType.NOTES,
|
||||
@@ -181,7 +173,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 500,
|
||||
@@ -194,7 +185,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
@@ -221,7 +211,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-emails',
|
||||
isActive: true,
|
||||
title: 'Emails',
|
||||
icon: 'IconMail',
|
||||
position: 600,
|
||||
@@ -234,7 +223,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-emails',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-emails',
|
||||
title: 'Emails',
|
||||
type: WidgetType.EMAILS,
|
||||
@@ -261,7 +249,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'person-tab-calendar',
|
||||
isActive: true,
|
||||
title: 'Calendar',
|
||||
icon: 'IconCalendarEvent',
|
||||
position: 700,
|
||||
@@ -274,7 +261,6 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'person-widget-calendar',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'person-tab-calendar',
|
||||
title: 'Calendar',
|
||||
type: WidgetType.CALENDAR,
|
||||
|
||||
@@ -21,7 +21,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'default-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'default-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'default-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -61,7 +59,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'default-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -74,7 +71,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'default-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'default-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -101,7 +97,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'default-tab-tasks',
|
||||
isActive: true,
|
||||
title: 'Tasks',
|
||||
icon: 'IconCheckbox',
|
||||
position: 300,
|
||||
@@ -114,7 +109,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'default-widget-tasks',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'default-tab-tasks',
|
||||
title: 'Tasks',
|
||||
type: WidgetType.TASKS,
|
||||
@@ -141,7 +135,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'default-tab-notes',
|
||||
isActive: true,
|
||||
title: 'Notes',
|
||||
icon: 'IconNotes',
|
||||
position: 400,
|
||||
@@ -154,7 +147,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'default-widget-notes',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'default-tab-notes',
|
||||
title: 'Notes',
|
||||
type: WidgetType.NOTES,
|
||||
@@ -181,7 +173,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'default-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 500,
|
||||
@@ -194,7 +185,6 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'default-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'default-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
|
||||
@@ -21,7 +21,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'task-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -34,7 +33,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'task-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'task-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -58,7 +56,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'task-widget-note',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'task-tab-fields',
|
||||
title: 'Note',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
@@ -92,7 +89,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'task-tab-note',
|
||||
isActive: true,
|
||||
title: 'Note',
|
||||
icon: 'IconNotes',
|
||||
position: 150,
|
||||
@@ -105,7 +101,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'task-widget-note',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'task-tab-note',
|
||||
title: 'Note',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
@@ -139,7 +134,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'task-tab-timeline',
|
||||
isActive: true,
|
||||
title: 'Timeline',
|
||||
icon: 'IconTimelineEvent',
|
||||
position: 200,
|
||||
@@ -152,7 +146,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'task-widget-timeline',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'task-tab-timeline',
|
||||
title: 'Timeline',
|
||||
type: WidgetType.TIMELINE,
|
||||
@@ -179,7 +172,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'task-tab-files',
|
||||
isActive: true,
|
||||
title: 'Files',
|
||||
icon: 'IconPaperclip',
|
||||
position: 300,
|
||||
@@ -192,7 +184,6 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'task-widget-files',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'task-tab-files',
|
||||
title: 'Files',
|
||||
type: WidgetType.FILES,
|
||||
|
||||
@@ -26,7 +26,6 @@ export const DEFAULT_WORKFLOW_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'workflow-tab-flow',
|
||||
isActive: true,
|
||||
title: 'Flow',
|
||||
position: 100,
|
||||
layoutMode: PageLayoutTabLayoutMode.CANVAS,
|
||||
@@ -39,7 +38,6 @@ export const DEFAULT_WORKFLOW_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'workflow-widget-flow',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'workflow-tab-flow',
|
||||
title: 'Flow',
|
||||
type: WidgetType.WORKFLOW,
|
||||
|
||||
-4
@@ -27,7 +27,6 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'workflow-run-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
position: 100,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
@@ -40,7 +39,6 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'workflow-run-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'workflow-run-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -68,7 +66,6 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'workflow-run-tab-flow',
|
||||
isActive: true,
|
||||
title: 'Flow',
|
||||
position: 200,
|
||||
layoutMode: PageLayoutTabLayoutMode.CANVAS,
|
||||
@@ -81,7 +78,6 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'workflow-run-widget-flow',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'workflow-run-tab-flow',
|
||||
title: 'Flow',
|
||||
type: WidgetType.WORKFLOW_RUN,
|
||||
|
||||
-4
@@ -27,7 +27,6 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'workflow-version-tab-fields',
|
||||
isActive: true,
|
||||
title: 'Home',
|
||||
icon: 'IconHome',
|
||||
position: 100,
|
||||
@@ -40,7 +39,6 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'workflow-version-widget-fields',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'workflow-version-tab-fields',
|
||||
title: 'Fields',
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -68,7 +66,6 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id: 'workflow-version-tab-flow',
|
||||
isActive: true,
|
||||
title: 'Flow',
|
||||
icon: 'IconSettings',
|
||||
position: 200,
|
||||
@@ -81,7 +78,6 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'workflow-version-widget-flow',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'workflow-version-tab-flow',
|
||||
title: 'Flow',
|
||||
type: WidgetType.WORKFLOW_VERSION,
|
||||
|
||||
-1
@@ -8,7 +8,6 @@ export const PAGE_LAYOUT_WIDGET_FRAGMENT = gql`
|
||||
objectMetadataId
|
||||
createdAt
|
||||
updatedAt
|
||||
isActive
|
||||
deletedAt
|
||||
conditionalDisplay
|
||||
conditionalAvailabilityExpression
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -47,7 +46,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
layoutMode,
|
||||
pageLayoutId: '',
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -47,7 +46,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
layoutMode,
|
||||
pageLayoutId: '',
|
||||
|
||||
-2
@@ -79,7 +79,6 @@ describe('useCreatePageLayoutGraphWidget', () => {
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
title: 'Tab 1',
|
||||
isActive: true,
|
||||
position: 0,
|
||||
pageLayoutId: '',
|
||||
widgets: [],
|
||||
@@ -163,7 +162,6 @@ describe('useCreatePageLayoutGraphWidget', () => {
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
title: 'Tab 1',
|
||||
isActive: true,
|
||||
position: 0,
|
||||
pageLayoutId: '',
|
||||
widgets: [],
|
||||
|
||||
-1
@@ -308,7 +308,6 @@ describe('useCreatePageLayoutTab', () => {
|
||||
id: 'existing-tab',
|
||||
applicationId: '',
|
||||
title: 'Existing Tab',
|
||||
isActive: true,
|
||||
position: 0,
|
||||
pageLayoutId: 'test-layout',
|
||||
widgets: [],
|
||||
|
||||
-2
@@ -25,7 +25,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -47,7 +46,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
pageLayoutId: '',
|
||||
widgets,
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -46,7 +45,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
pageLayoutId: '',
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -46,7 +45,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
pageLayoutId: '',
|
||||
|
||||
-2
@@ -24,7 +24,6 @@ const makeWidget = (
|
||||
id,
|
||||
pageLayoutTabId: tabId,
|
||||
title: id,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
gridPosition: { column: 0, columnSpan: 1, row: 0, rowSpan: 1 },
|
||||
configuration: { __typename: 'FieldsConfiguration' as const },
|
||||
@@ -46,7 +45,6 @@ const makeTab = (
|
||||
id,
|
||||
applicationId: '',
|
||||
title: id,
|
||||
isActive: true,
|
||||
position,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
pageLayoutId: '',
|
||||
|
||||
-2
@@ -90,7 +90,6 @@ describe('usePageLayoutDraftState', () => {
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
title: 'Tab 1',
|
||||
isActive: true,
|
||||
position: 0,
|
||||
pageLayoutId: '',
|
||||
createdAt: new Date().toISOString(),
|
||||
@@ -101,7 +100,6 @@ describe('usePageLayoutDraftState', () => {
|
||||
id: 'widget-1',
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'New Widget',
|
||||
isActive: true,
|
||||
type: WidgetType.GRAPH,
|
||||
gridPosition: { row: 2, column: 2, rowSpan: 2, columnSpan: 2 },
|
||||
configuration: {
|
||||
|
||||
-5
@@ -35,7 +35,6 @@ describe('usePageLayoutWithRelationWidgets', () => {
|
||||
applicationId: '',
|
||||
id: 'tab-1',
|
||||
title: 'Fields',
|
||||
isActive: true,
|
||||
icon: 'IconList',
|
||||
position: 100,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
@@ -49,7 +48,6 @@ describe('usePageLayoutWithRelationWidgets', () => {
|
||||
id: 'widget-fields',
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Fields',
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
objectMetadataId: null,
|
||||
gridPosition: {
|
||||
@@ -73,7 +71,6 @@ describe('usePageLayoutWithRelationWidgets', () => {
|
||||
id: 'widget-notes',
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Notes',
|
||||
isActive: true,
|
||||
type: WidgetType.NOTES,
|
||||
objectMetadataId: null,
|
||||
gridPosition: {
|
||||
@@ -96,7 +93,6 @@ describe('usePageLayoutWithRelationWidgets', () => {
|
||||
id: 'widget-other',
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Other',
|
||||
isActive: true,
|
||||
type: WidgetType.GRAPH,
|
||||
objectMetadataId: null,
|
||||
gridPosition: {
|
||||
@@ -221,7 +217,6 @@ describe('usePageLayoutWithRelationWidgets', () => {
|
||||
id: 'widget-other',
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Other',
|
||||
isActive: true,
|
||||
type: WidgetType.GRAPH,
|
||||
objectMetadataId: null,
|
||||
gridPosition: {
|
||||
|
||||
@@ -54,7 +54,6 @@ export const useCreatePageLayoutTab = ({
|
||||
const newTab: PageLayoutTab = {
|
||||
id: newTabId,
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: title || `Tab ${tabsLength + 1}`,
|
||||
position: maxPosition + 1,
|
||||
pageLayoutId: pageLayoutId,
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ export const useCreatePendingFieldsWidgetViews = () => {
|
||||
if (widget.type !== WidgetType.FIELDS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const viewId = getWidgetConfigurationViewId(widget.configuration);
|
||||
|
||||
return isDefined(viewId) && !persistedWidgetIds.has(widget.id);
|
||||
|
||||
@@ -2,14 +2,18 @@ import { PageLayoutComponentInstanceContext } from '@/page-layout/states/context
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { removeWidgetFromTab } from '@/page-layout/utils/removeWidgetFromTab';
|
||||
import { removeWidgetLayoutFromTab } from '@/page-layout/utils/removeWidgetLayoutFromTab';
|
||||
import { useDeleteViewForFieldsWidget } from '@/page-layout/widgets/fields/hooks/useDeleteViewForFieldsWidget';
|
||||
import { useDeleteViewForRecordTableWidget } from '@/page-layout/widgets/record-table/hooks/useDeleteViewForRecordTableWidget';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { WidgetType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
|
||||
const pageLayoutId = useAvailableComponentInstanceIdOrThrow(
|
||||
@@ -34,6 +38,16 @@ export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
|
||||
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const { deleteViewForFieldsWidget } = useDeleteViewForFieldsWidget();
|
||||
|
||||
const { deleteViewForRecordTableWidget } =
|
||||
useDeleteViewForRecordTableWidget();
|
||||
|
||||
const pageLayoutPersistedState = useAtomComponentStateCallbackState(
|
||||
pageLayoutPersistedComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const deletePageLayoutWidget = useCallback(
|
||||
@@ -47,6 +61,43 @@ export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
|
||||
tab.widgets.some((widget) => widget.id === widgetId),
|
||||
);
|
||||
|
||||
const widgetToDelete = tabWithWidget?.widgets.find(
|
||||
(widget) => widget.id === widgetId,
|
||||
);
|
||||
|
||||
const persisted = store.get(pageLayoutPersistedState);
|
||||
const persistedWidgetIds = new Set(
|
||||
persisted?.tabs.flatMap((tab) =>
|
||||
tab.widgets.map((widget) => widget.id),
|
||||
) ?? [],
|
||||
);
|
||||
|
||||
const isWidgetPersisted = persistedWidgetIds.has(widgetId);
|
||||
|
||||
if (
|
||||
isWidgetPersisted &&
|
||||
isDefined(widgetToDelete) &&
|
||||
widgetToDelete.type === WidgetType.RECORD_TABLE &&
|
||||
'viewId' in widgetToDelete.configuration &&
|
||||
isDefined(widgetToDelete.configuration.viewId)
|
||||
) {
|
||||
deleteViewForRecordTableWidget(
|
||||
widgetToDelete.configuration.viewId as string,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isWidgetPersisted &&
|
||||
isDefined(widgetToDelete) &&
|
||||
widgetToDelete.type === WidgetType.FIELDS &&
|
||||
'viewId' in widgetToDelete.configuration &&
|
||||
isDefined(widgetToDelete.configuration.viewId)
|
||||
) {
|
||||
deleteViewForFieldsWidget(
|
||||
widgetToDelete.configuration.viewId as string,
|
||||
);
|
||||
}
|
||||
|
||||
const tabId = tabWithWidget?.id;
|
||||
|
||||
if (isDefined(tabId)) {
|
||||
@@ -73,9 +124,12 @@ export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
|
||||
},
|
||||
[
|
||||
closeSidePanelMenu,
|
||||
deleteViewForFieldsWidget,
|
||||
deleteViewForRecordTableWidget,
|
||||
pageLayoutCurrentLayoutsState,
|
||||
pageLayoutDraftState,
|
||||
pageLayoutEditingWidgetIdState,
|
||||
pageLayoutPersistedState,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
+3
-5
@@ -27,22 +27,20 @@ export const usePageLayoutTabWithVisibleWidgetsOrThrow = (
|
||||
throw new Error('Tab not found');
|
||||
}
|
||||
|
||||
const activeWidgets = tab.widgets.filter((widget) => widget.isActive);
|
||||
|
||||
if (isPageLayoutInEditMode) {
|
||||
return {
|
||||
...tab,
|
||||
widgets:
|
||||
tab.layoutMode === PageLayoutTabLayoutMode.VERTICAL_LIST
|
||||
? sortWidgetsByVerticalListPosition(activeWidgets)
|
||||
: activeWidgets,
|
||||
? sortWidgetsByVerticalListPosition(tab.widgets)
|
||||
: tab.widgets,
|
||||
};
|
||||
}
|
||||
|
||||
const context = buildWidgetVisibilityContext({ isMobile, isInSidePanel });
|
||||
|
||||
const visibleWidgets = filterVisibleWidgets({
|
||||
widgets: activeWidgets,
|
||||
widgets: tab.widgets,
|
||||
context,
|
||||
});
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@ import { useExitLayoutCustomizationMode } from '@/layout-customization/hooks/use
|
||||
import { useInvalidateMetadataStore } from '@/metadata-store/hooks/useInvalidateMetadataStore';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { fieldsWidgetEditorModeDraftComponentState } from '@/page-layout/states/fieldsWidgetEditorModeDraftComponentState';
|
||||
import { fieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/fieldsWidgetGroupsDraftComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsDraftComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsDraftComponentState';
|
||||
import { hasInitializedFieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/hasInitializedFieldsWidgetGroupsDraftComponentState';
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
@@ -54,28 +50,6 @@ export const useRefreshPageLayoutAfterReset = (
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const fieldsWidgetGroupsDraftState = useAtomComponentStateCallbackState(
|
||||
fieldsWidgetGroupsDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const fieldsWidgetUngroupedFieldsDraftState =
|
||||
useAtomComponentStateCallbackState(
|
||||
fieldsWidgetUngroupedFieldsDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const fieldsWidgetEditorModeDraftState = useAtomComponentStateCallbackState(
|
||||
fieldsWidgetEditorModeDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const hasInitializedFieldsWidgetGroupsDraftState =
|
||||
useAtomComponentStateCallbackState(
|
||||
hasInitializedFieldsWidgetGroupsDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const refreshPageLayoutAfterReset = useCallback(
|
||||
async (collectAffectedViewIds: (layout: PageLayout) => Set<string>) => {
|
||||
const { data } = await client.query({
|
||||
@@ -99,11 +73,6 @@ export const useRefreshPageLayoutAfterReset = (
|
||||
);
|
||||
}
|
||||
|
||||
store.set(fieldsWidgetGroupsDraftState, {});
|
||||
store.set(fieldsWidgetUngroupedFieldsDraftState, {});
|
||||
store.set(fieldsWidgetEditorModeDraftState, {});
|
||||
store.set(hasInitializedFieldsWidgetGroupsDraftState, {});
|
||||
|
||||
setIsPageLayoutInEditMode(false);
|
||||
exitLayoutCustomizationMode();
|
||||
evictViewMetadataForViewIds(store, affectedViewIds);
|
||||
@@ -116,10 +85,6 @@ export const useRefreshPageLayoutAfterReset = (
|
||||
pageLayoutPersistedState,
|
||||
pageLayoutDraftState,
|
||||
pageLayoutCurrentLayoutsState,
|
||||
fieldsWidgetGroupsDraftState,
|
||||
fieldsWidgetUngroupedFieldsDraftState,
|
||||
fieldsWidgetEditorModeDraftState,
|
||||
hasInitializedFieldsWidgetGroupsDraftState,
|
||||
setIsPageLayoutInEditMode,
|
||||
exitLayoutCustomizationMode,
|
||||
invalidateMetadataStore,
|
||||
|
||||
+47
@@ -3,13 +3,18 @@ import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pag
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutDraggedAreaComponentState } from '@/page-layout/states/pageLayoutDraggedAreaComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { getWidgetConfigurationViewId } from '@/page-layout/utils/getWidgetConfigurationViewId';
|
||||
import { removeWidgetFromTab } from '@/page-layout/utils/removeWidgetFromTab';
|
||||
import { removeWidgetLayoutFromTab } from '@/page-layout/utils/removeWidgetLayoutFromTab';
|
||||
import { useDeleteViewForFieldsWidget } from '@/page-layout/widgets/fields/hooks/useDeleteViewForFieldsWidget';
|
||||
import { useDeleteViewForRecordTableWidget } from '@/page-layout/widgets/record-table/hooks/useDeleteViewForRecordTableWidget';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { WidgetType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useRemovePageLayoutWidgetAndPreservePosition = (
|
||||
pageLayoutIdFromProps?: string,
|
||||
@@ -39,6 +44,16 @@ export const useRemovePageLayoutWidgetAndPreservePosition = (
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const { deleteViewForFieldsWidget } = useDeleteViewForFieldsWidget();
|
||||
|
||||
const { deleteViewForRecordTableWidget } =
|
||||
useDeleteViewForRecordTableWidget();
|
||||
|
||||
const pageLayoutPersistedState = useAtomComponentStateCallbackState(
|
||||
pageLayoutPersistedComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const removePageLayoutWidgetAndPreservePosition = useCallback(
|
||||
@@ -50,6 +65,35 @@ export const useRemovePageLayoutWidgetAndPreservePosition = (
|
||||
tab.widgets.some((widget) => widget.id === widgetId),
|
||||
);
|
||||
|
||||
const widgetToRemove = tabWithWidget?.widgets.find(
|
||||
(widget) => widget.id === widgetId,
|
||||
);
|
||||
|
||||
const persisted = store.get(pageLayoutPersistedState);
|
||||
const persistedWidgetIds = new Set(
|
||||
persisted?.tabs.flatMap((tab) =>
|
||||
tab.widgets.map((widget) => widget.id),
|
||||
) ?? [],
|
||||
);
|
||||
|
||||
const isWidgetPersisted = persistedWidgetIds.has(widgetId);
|
||||
|
||||
if (isWidgetPersisted && isDefined(widgetToRemove)) {
|
||||
const viewId = getWidgetConfigurationViewId(
|
||||
widgetToRemove.configuration,
|
||||
);
|
||||
|
||||
if (isDefined(viewId)) {
|
||||
if (widgetToRemove.type === WidgetType.RECORD_TABLE) {
|
||||
deleteViewForRecordTableWidget(viewId);
|
||||
}
|
||||
|
||||
if (widgetToRemove.type === WidgetType.FIELDS) {
|
||||
deleteViewForFieldsWidget(viewId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tabId = tabWithWidget?.id;
|
||||
|
||||
if (!isDefined(tabId)) {
|
||||
@@ -87,10 +131,13 @@ export const useRemovePageLayoutWidgetAndPreservePosition = (
|
||||
store.set(pageLayoutEditingWidgetIdState, null);
|
||||
},
|
||||
[
|
||||
deleteViewForFieldsWidget,
|
||||
deleteViewForRecordTableWidget,
|
||||
pageLayoutCurrentLayoutsState,
|
||||
pageLayoutDraftState,
|
||||
pageLayoutDraggedAreaState,
|
||||
pageLayoutEditingWidgetIdState,
|
||||
pageLayoutPersistedState,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
+2
-7
@@ -18,15 +18,10 @@ export const pageLayoutsWithRelationsSelector = createAtomSelector<
|
||||
const allFlatWidgets = get(metadataStoreState, 'pageLayoutWidgets')
|
||||
.current as FlatPageLayoutWidget[];
|
||||
|
||||
const activeFlatTabs = allFlatTabs.filter((tab) => tab.isActive);
|
||||
const activeFlatWidgets = allFlatWidgets.filter(
|
||||
(widget) => widget.isActive,
|
||||
);
|
||||
|
||||
const tabsByPageLayoutId = new Map<string, FlatPageLayoutTab[]>();
|
||||
const widgetsByTabId = new Map<string, FlatPageLayoutWidget[]>();
|
||||
|
||||
for (const tab of activeFlatTabs) {
|
||||
for (const tab of allFlatTabs) {
|
||||
const existing = tabsByPageLayoutId.get(tab.pageLayoutId);
|
||||
|
||||
if (isDefined(existing)) {
|
||||
@@ -36,7 +31,7 @@ export const pageLayoutsWithRelationsSelector = createAtomSelector<
|
||||
}
|
||||
}
|
||||
|
||||
for (const widget of activeFlatWidgets) {
|
||||
for (const widget of allFlatWidgets) {
|
||||
const existing = widgetsByTabId.get(widget.pageLayoutTabId);
|
||||
|
||||
if (isDefined(existing)) {
|
||||
|
||||
@@ -11,7 +11,6 @@ describe('addWidgetToTab', () => {
|
||||
const mockWidget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'widget-1',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Test Widget',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -32,7 +31,6 @@ describe('addWidgetToTab', () => {
|
||||
{
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 1',
|
||||
position: 0,
|
||||
pageLayoutId: 'layout-1',
|
||||
@@ -44,7 +42,6 @@ describe('addWidgetToTab', () => {
|
||||
{
|
||||
id: 'tab-2',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 2',
|
||||
position: 1,
|
||||
pageLayoutId: 'layout-1',
|
||||
|
||||
-2
@@ -12,7 +12,6 @@ describe('convertLayoutsToWidgets', () => {
|
||||
const mockWidgets: PageLayoutWidget[] = [
|
||||
{
|
||||
id: 'widget-1',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 1',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -35,7 +34,6 @@ describe('convertLayoutsToWidgets', () => {
|
||||
},
|
||||
{
|
||||
id: 'widget-2',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 2',
|
||||
type: WidgetType.GRAPH,
|
||||
|
||||
-5
@@ -20,7 +20,6 @@ describe('convertPageLayoutToTabLayouts', () => {
|
||||
{
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 1',
|
||||
position: 0,
|
||||
pageLayoutId: 'page-layout-1',
|
||||
@@ -28,7 +27,6 @@ describe('convertPageLayoutToTabLayouts', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'widget-1',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 1',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -47,7 +45,6 @@ describe('convertPageLayoutToTabLayouts', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'widget-2',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 2',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -102,7 +99,6 @@ describe('convertPageLayoutToTabLayouts', () => {
|
||||
{
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 1',
|
||||
position: 0,
|
||||
pageLayoutId: 'page-layout-1',
|
||||
@@ -110,7 +106,6 @@ describe('convertPageLayoutToTabLayouts', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: 'rich-text-widget',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Rich Text',
|
||||
type: WidgetType.STANDALONE_RICH_TEXT,
|
||||
|
||||
-1
@@ -23,7 +23,6 @@ const createMockWidget = (
|
||||
},
|
||||
): PageLayoutWidget => ({
|
||||
id: 'widget-1',
|
||||
isActive: true,
|
||||
type: WidgetType.GRAPH,
|
||||
title: 'Test',
|
||||
objectMetadataId: null,
|
||||
|
||||
-1
@@ -12,7 +12,6 @@ describe('filterVisibleWidgets', () => {
|
||||
): PageLayoutTab['widgets'][0] => ({
|
||||
__typename: 'PageLayoutWidget',
|
||||
id,
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: `Widget ${id}`,
|
||||
type: WidgetType.FIELDS,
|
||||
|
||||
-1
@@ -5,7 +5,6 @@ describe('getPageLayoutTabListInitialActiveTabId', () => {
|
||||
const createMockTab = (id: string): PageLayoutTab => ({
|
||||
id,
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
pageLayoutId: 'page-layout-1',
|
||||
title: `Tab ${id}`,
|
||||
position: 0,
|
||||
|
||||
-1
@@ -10,7 +10,6 @@ describe('getTabsByDisplayMode', () => {
|
||||
const createMockTab = (id: string): PageLayoutTab => ({
|
||||
id,
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
pageLayoutId: 'page-layout-1',
|
||||
title: `Tab ${id}`,
|
||||
position: 0,
|
||||
|
||||
-2
@@ -12,7 +12,6 @@ describe('getTabsWithVisibleWidgets', () => {
|
||||
): PageLayoutTab['widgets'][0] => ({
|
||||
__typename: 'PageLayoutWidget',
|
||||
id,
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: `Widget ${id}`,
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -42,7 +41,6 @@ describe('getTabsWithVisibleWidgets', () => {
|
||||
__typename: 'PageLayoutTab',
|
||||
applicationId: '',
|
||||
id,
|
||||
isActive: true,
|
||||
pageLayoutId: 'page-layout-1',
|
||||
title: `Tab ${id}`,
|
||||
position: 0,
|
||||
|
||||
-2
@@ -10,7 +10,6 @@ import {
|
||||
describe('prepareGridLayoutItemsWithPlaceholders', () => {
|
||||
const createMockWidget = (id: string): PageLayoutWidget => ({
|
||||
id,
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: `Test Widget ${id}`,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -216,7 +215,6 @@ describe('prepareGridLayoutItemsWithPlaceholders', () => {
|
||||
expect(resultWidget.createdAt).toBe(widget.createdAt);
|
||||
expect(resultWidget.updatedAt).toBe(widget.updatedAt);
|
||||
expect(resultWidget.deletedAt).toBe(widget.deletedAt);
|
||||
expect(resultWidget.isActive).toBe(widget.isActive);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
-5
@@ -12,7 +12,6 @@ describe('removeWidgetFromTab', () => {
|
||||
{
|
||||
id: 'tab-1',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 1',
|
||||
position: 0,
|
||||
pageLayoutId: 'layout-1',
|
||||
@@ -20,7 +19,6 @@ describe('removeWidgetFromTab', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget' as const,
|
||||
id: 'widget-1',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 1',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -39,7 +37,6 @@ describe('removeWidgetFromTab', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget' as const,
|
||||
id: 'widget-2',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-1',
|
||||
title: 'Widget 2',
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -65,7 +62,6 @@ describe('removeWidgetFromTab', () => {
|
||||
{
|
||||
id: 'tab-2',
|
||||
applicationId: '',
|
||||
isActive: true,
|
||||
title: 'Tab 2',
|
||||
position: 1,
|
||||
pageLayoutId: 'layout-1',
|
||||
@@ -73,7 +69,6 @@ describe('removeWidgetFromTab', () => {
|
||||
{
|
||||
__typename: 'PageLayoutWidget' as const,
|
||||
id: 'widget-3',
|
||||
isActive: true,
|
||||
pageLayoutTabId: 'tab-2',
|
||||
title: 'Widget 3',
|
||||
type: WidgetType.IFRAME,
|
||||
|
||||
@@ -28,7 +28,6 @@ export const createDefaultFieldWidget = ({
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELD,
|
||||
configuration: {
|
||||
__typename: 'FieldConfiguration',
|
||||
|
||||
@@ -23,7 +23,6 @@ export const createDefaultFieldsWidget = ({
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title: 'Fields',
|
||||
isActive: true,
|
||||
type: WidgetType.FIELDS,
|
||||
configuration: {
|
||||
__typename: 'FieldsConfiguration',
|
||||
|
||||
-1
@@ -18,7 +18,6 @@ export const createDefaultFrontComponentWidget = (
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
isActive: true,
|
||||
type: WidgetType.FRONT_COMPONENT,
|
||||
configuration: {
|
||||
__typename: 'FrontComponentConfiguration',
|
||||
|
||||
@@ -72,7 +72,6 @@ export const createDefaultGraphWidget = ({
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
isActive: true,
|
||||
type: WidgetType.GRAPH,
|
||||
configuration,
|
||||
gridPosition,
|
||||
|
||||
@@ -19,7 +19,6 @@ export const createDefaultIframeWidget = (
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
isActive: true,
|
||||
type: WidgetType.IFRAME,
|
||||
configuration: {
|
||||
configurationType: WidgetConfigurationType.IFRAME,
|
||||
|
||||
@@ -24,7 +24,6 @@ export const createDefaultRecordTableWidget = ({
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
isActive: true,
|
||||
type: WidgetType.RECORD_TABLE,
|
||||
configuration: {
|
||||
configurationType: WidgetConfigurationType.RECORD_TABLE,
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ export const createDefaultStandaloneRichTextWidget = (
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title: 'Untitled Rich Text',
|
||||
isActive: true,
|
||||
type: WidgetType.STANDALONE_RICH_TEXT,
|
||||
configuration: {
|
||||
configurationType: WidgetConfigurationType.STANDALONE_RICH_TEXT,
|
||||
|
||||
@@ -15,15 +15,13 @@ export const getTabsWithVisibleWidgets = ({
|
||||
isInSidePanel,
|
||||
isEditMode,
|
||||
}: GetTabsWithVisibleWidgetsParams): PageLayoutTab[] => {
|
||||
const activeTabs = tabs.filter((tab) => tab.isActive);
|
||||
|
||||
if (isEditMode) {
|
||||
return activeTabs;
|
||||
return tabs;
|
||||
}
|
||||
|
||||
const context = buildWidgetVisibilityContext({ isMobile, isInSidePanel });
|
||||
|
||||
const tabsWithFilteredWidgets = activeTabs.map((tab) => ({
|
||||
const tabsWithFilteredWidgets = tabs.map((tab) => ({
|
||||
...tab,
|
||||
widgets: filterVisibleWidgets({ widgets: tab.widgets, context }),
|
||||
}));
|
||||
@@ -32,7 +30,7 @@ export const getTabsWithVisibleWidgets = ({
|
||||
(tab) => tab.widgets.length > 0,
|
||||
);
|
||||
|
||||
if (tabsWithVisibleWidgets.length === 0 && activeTabs.length > 0) {
|
||||
if (tabsWithVisibleWidgets.length === 0 && tabs.length > 0) {
|
||||
return tabsWithFilteredWidgets.slice(0, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ const getRelationFieldWidgetToInsert = (
|
||||
id: `${DYNAMIC_RELATION_WIDGET_ID_PREFIX}${field.id}-${field.label}`,
|
||||
pageLayoutTabId: tabId,
|
||||
title: field.label,
|
||||
isActive: true,
|
||||
type: WidgetType.FIELD,
|
||||
objectMetadataId: null,
|
||||
gridPosition: {
|
||||
|
||||
+13
-4
@@ -9,6 +9,7 @@ import { useResolveFieldMetadataIdFromNameOrId } from '@/page-layout/hooks/useRe
|
||||
import { isFieldWidget } from '@/page-layout/widgets/field/utils/isFieldWidget';
|
||||
import { useCurrentWidget } from '@/page-layout/widgets/hooks/useCurrentWidget';
|
||||
import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
||||
import { indexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/indexViewIdFromObjectMetadataItemFamilySelector';
|
||||
import { styled } from '@linaria/react';
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
TooltipPosition,
|
||||
} from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { RelationType } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledLinkContainer = styled.div`
|
||||
@@ -33,14 +35,21 @@ const StyledLinkContainer = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSeeAllButtonWrapper = styled.div`
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
const StyledSeeAllButtonWrapper = styled.div<{ isMobile: boolean }>`
|
||||
opacity: ${({ isMobile }) => (isMobile ? '1' : '0')};
|
||||
pointer-events: none;
|
||||
transition: opacity ${themeCssVariables.animation.duration.instant}s ease;
|
||||
|
||||
.widget:hover & {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
`;
|
||||
|
||||
export const WidgetActionFieldSeeAll = () => {
|
||||
const widget = useCurrentWidget();
|
||||
const targetRecord = useTargetRecord();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: targetRecord.targetObjectNameSingular,
|
||||
@@ -136,7 +145,7 @@ export const WidgetActionFieldSeeAll = () => {
|
||||
<div id={tooltipId}>
|
||||
<StyledLinkContainer>
|
||||
<Link to={filterLinkHref} data-testid="widget-see-all-link">
|
||||
<StyledSeeAllButtonWrapper>
|
||||
<StyledSeeAllButtonWrapper isMobile={isMobile}>
|
||||
<LightIconButton Icon={IconArrowUpRight} accent="secondary" />
|
||||
</StyledSeeAllButtonWrapper>
|
||||
</Link>
|
||||
|
||||
@@ -205,10 +205,6 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
|
||||
variant={variant}
|
||||
hasHeader={showHeader}
|
||||
isEditable={isWidgetEditable}
|
||||
isInVerticalListTab={
|
||||
layoutMode === PageLayoutTabLayoutMode.VERTICAL_LIST
|
||||
}
|
||||
isMobile={isMobile}
|
||||
hasInteractiveContent={widget.type === WidgetType.RECORD_TABLE}
|
||||
>
|
||||
{hasAccess ? (
|
||||
|
||||
-18
@@ -143,7 +143,6 @@ const createPageLayoutWithWidget = (
|
||||
tabs: [
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: TAB_ID_OVERVIEW,
|
||||
title: 'Overview',
|
||||
@@ -253,7 +252,6 @@ export const WithNumberChart: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_NUMBER_CHART,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -340,7 +338,6 @@ export const WithGaugeChart: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_GAUGE_CHART,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -427,7 +424,6 @@ export const WithBarChart: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_BAR_CHART,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -525,7 +521,6 @@ export const SmallWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_SMALL,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -619,7 +614,6 @@ export const MediumWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_MEDIUM,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -717,7 +711,6 @@ export const LargeWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_LARGE,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -815,7 +808,6 @@ export const WideWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_WIDE,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -909,7 +901,6 @@ export const TallWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_TALL,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -1008,7 +999,6 @@ export const WithManyToOneRelationFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_MANY_TO_ONE_RELATION,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1127,7 +1117,6 @@ export const WithOneToManyRelationFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_ONE_TO_MANY_RELATION,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1238,7 +1227,6 @@ export const OneToManyRelationFieldWidgetWithSeeAllButton: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_ONE_TO_MANY_RELATION,
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1375,7 +1363,6 @@ export const OnMobile: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-mobile',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -1473,7 +1460,6 @@ export const InSidePanel: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-side-panel',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.GRAPH,
|
||||
@@ -1631,7 +1617,6 @@ export const Catalog: CatalogStory<Story, typeof WidgetRenderer> = {
|
||||
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: WIDGET_ID_CATALOG,
|
||||
pageLayoutTabId:
|
||||
variant === 'side-column' ? 'pinned-tab' : TAB_ID_OVERVIEW,
|
||||
@@ -1738,7 +1723,6 @@ export const Catalog: CatalogStory<Story, typeof WidgetRenderer> = {
|
||||
? [
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: 'pinned-tab',
|
||||
title: 'Pinned Tab',
|
||||
@@ -1751,7 +1735,6 @@ export const Catalog: CatalogStory<Story, typeof WidgetRenderer> = {
|
||||
},
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: 'other-tab',
|
||||
title: 'Other Tab',
|
||||
@@ -1766,7 +1749,6 @@ export const Catalog: CatalogStory<Story, typeof WidgetRenderer> = {
|
||||
: [
|
||||
{
|
||||
__typename: 'PageLayoutTab',
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: TAB_ID_OVERVIEW,
|
||||
title: 'Overview',
|
||||
|
||||
+43
-11
@@ -1,4 +1,5 @@
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useRecordFieldsScopeContextOrThrow } from '@/object-record/record-field-list/contexts/RecordFieldsScopeContext';
|
||||
import { RecordDetailMorphRelationSectionDropdown } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailMorphRelationSectionDropdown';
|
||||
import { RecordDetailRelationSectionDropdown } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdown';
|
||||
import {
|
||||
@@ -16,11 +17,15 @@ import {
|
||||
type FieldRelationMetadata,
|
||||
} from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { isFieldMorphRelation } from '@/object-record/record-field/ui/types/guards/isFieldMorphRelation';
|
||||
import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { styled } from '@linaria/react';
|
||||
import { CustomError } from 'twenty-shared/utils';
|
||||
import { IconPencil, IconPlus } from 'twenty-ui/display';
|
||||
import { IconPencil } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { RelationType } from '~/generated-metadata/graphql';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type FieldWidgetRelationEditActionProps = {
|
||||
fieldDefinition:
|
||||
@@ -29,15 +34,30 @@ type FieldWidgetRelationEditActionProps = {
|
||||
recordId: string;
|
||||
};
|
||||
|
||||
const StyledEditButtonWrapper = styled.div`
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
const StyledEditButtonWrapper = styled.div<{
|
||||
isDropdownOpen: boolean;
|
||||
isMobile: boolean;
|
||||
}>`
|
||||
opacity: ${({ isDropdownOpen, isMobile }) =>
|
||||
isDropdownOpen ? '1' : isMobile ? '1' : '0'};
|
||||
pointer-events: ${({ isDropdownOpen }) => (isDropdownOpen ? 'auto' : 'none')};
|
||||
transition: ${({ isDropdownOpen }) =>
|
||||
isDropdownOpen
|
||||
? 'none'
|
||||
: `opacity ${themeCssVariables.animation.duration.instant}s ease`};
|
||||
|
||||
.widget:hover & {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
`;
|
||||
|
||||
export const FieldWidgetRelationEditAction = ({
|
||||
fieldDefinition,
|
||||
recordId,
|
||||
}: FieldWidgetRelationEditActionProps) => {
|
||||
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) =>
|
||||
@@ -72,14 +92,26 @@ export const FieldWidgetRelationEditAction = ({
|
||||
|
||||
const isMorphRelation = isFieldMorphRelation(fieldDefinition);
|
||||
|
||||
const triggerIcon =
|
||||
fieldDefinition.metadata.relationType === RelationType.MANY_TO_ONE
|
||||
? IconPencil
|
||||
: IconPlus;
|
||||
const relationSelectionDropdownId =
|
||||
getRecordFieldCardRelationPickerDropdownId({
|
||||
fieldDefinition,
|
||||
recordId,
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
const isDropdownOpen = useAtomComponentStateValue(
|
||||
isDropdownOpenComponentState,
|
||||
relationSelectionDropdownId,
|
||||
);
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const dropdownTriggerClickableComponent = (
|
||||
<StyledEditButtonWrapper>
|
||||
<LightIconButton Icon={triggerIcon} accent="secondary" />
|
||||
<StyledEditButtonWrapper
|
||||
isDropdownOpen={isDropdownOpen}
|
||||
isMobile={isMobile}
|
||||
>
|
||||
<LightIconButton Icon={IconPencil} accent="secondary" />
|
||||
</StyledEditButtonWrapper>
|
||||
);
|
||||
|
||||
|
||||
-18
@@ -291,7 +291,6 @@ const createPageLayoutWithWidget = (
|
||||
tabs: [
|
||||
{
|
||||
__typename: 'PageLayoutTab' as const,
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: TAB_ID_OVERVIEW,
|
||||
title: 'Overview',
|
||||
@@ -333,7 +332,6 @@ export const TextFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-text-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -427,7 +425,6 @@ export const AddressFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-address-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -524,7 +521,6 @@ export const NumberFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-number-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -618,7 +614,6 @@ export const LinkFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-link-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -712,7 +707,6 @@ export const ManyToOneRelationFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-relation-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -816,7 +810,6 @@ export const OneToManyRelationFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-one-to-many-relation-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -912,7 +905,6 @@ export const BooleanFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-boolean-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1005,7 +997,6 @@ export const CurrencyFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-currency-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1098,7 +1089,6 @@ export const EmailsFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-emails-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1192,7 +1182,6 @@ export const PhonesFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-phones-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1286,7 +1275,6 @@ export const SelectFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-select-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1381,7 +1369,6 @@ export const MultiSelectFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-multi-select-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1479,7 +1466,6 @@ export const TimelineActivityRelationFieldWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-timeline-activity-relation-field',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1578,7 +1564,6 @@ export const ManyToOneRelationCardWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-relation-card',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1690,7 +1675,6 @@ export const OneToManyRelationCardWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-one-to-many-relation-card',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1785,7 +1769,6 @@ export const TimelineActivityRelationCardWidget: Story = {
|
||||
render: () => {
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-timeline-activity-relation-card',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
@@ -1946,7 +1929,6 @@ export const OneToManyRelationCardWidgetWithProgressiveLoading: Story = {
|
||||
|
||||
const widget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-one-to-many-relation-card-progressive',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELD,
|
||||
|
||||
-4
@@ -141,7 +141,6 @@ const createPageLayoutWithWidget = (
|
||||
tabs: [
|
||||
{
|
||||
__typename: 'PageLayoutTab' as const,
|
||||
isActive: true,
|
||||
applicationId: '',
|
||||
id: TAB_ID_OVERVIEW,
|
||||
title: 'Overview',
|
||||
@@ -160,7 +159,6 @@ const createPageLayoutWithWidget = (
|
||||
|
||||
const createFieldsWidget = (viewId: string | null): PageLayoutWidget => ({
|
||||
__typename: 'PageLayoutWidget',
|
||||
isActive: true,
|
||||
id: 'widget-fields',
|
||||
pageLayoutTabId: TAB_ID_OVERVIEW,
|
||||
type: WidgetType.FIELDS,
|
||||
@@ -215,7 +213,6 @@ const createViewField = (
|
||||
fieldMetadataId,
|
||||
position,
|
||||
isVisible: true,
|
||||
isActive: true,
|
||||
size: 200,
|
||||
aggregateOperation: null,
|
||||
viewId: FIELDS_VIEW_ID,
|
||||
@@ -233,7 +230,6 @@ const createViewFieldGroup = (
|
||||
name,
|
||||
position,
|
||||
isVisible,
|
||||
isActive: true,
|
||||
viewId: FIELDS_VIEW_ID,
|
||||
viewFields,
|
||||
});
|
||||
|
||||
+14
-65
@@ -29,12 +29,9 @@ export const useFieldsWidgetGroups = ({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const { groups, displayMode } = useMemo<{
|
||||
groups: FieldsWidgetGroup[];
|
||||
displayMode: FieldsWidgetDisplayMode;
|
||||
}>(() => {
|
||||
const groups = useMemo<FieldsWidgetGroup[]>(() => {
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
return { groups: [], displayMode: 'grouped' };
|
||||
return [];
|
||||
}
|
||||
|
||||
if (isDefined(view) && isNonEmptyArray(view.viewFieldGroups)) {
|
||||
@@ -44,7 +41,7 @@ export const useFieldsWidgetGroups = ({
|
||||
|
||||
let globalIndex = 0;
|
||||
|
||||
const resultGroups = sortedGroups
|
||||
return sortedGroups
|
||||
.filter((group) => group.isVisible)
|
||||
.map((group) => {
|
||||
const groupFields = [...(group.viewFields ?? [])].sort(
|
||||
@@ -82,76 +79,28 @@ export const useFieldsWidgetGroups = ({
|
||||
};
|
||||
})
|
||||
.filter((group) => group.fields.length > 0);
|
||||
|
||||
return { groups: resultGroups, displayMode: 'grouped' };
|
||||
}
|
||||
|
||||
if (isDefined(view) && isNonEmptyArray(view.viewFields)) {
|
||||
let globalIndex = 0;
|
||||
|
||||
const fields: FieldsWidgetGroupField[] = [...view.viewFields]
|
||||
.sort((a, b) => a.position - b.position)
|
||||
.filter((viewField) => viewField.isVisible)
|
||||
.map((viewField) => {
|
||||
const fieldMetadataItem = objectMetadataItem.fields.find(
|
||||
(f) => f.id === viewField.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataItem)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
fieldMetadataItem,
|
||||
position: viewField.position,
|
||||
isVisible: viewField.isVisible,
|
||||
globalIndex: globalIndex++,
|
||||
};
|
||||
})
|
||||
.filter(isDefined);
|
||||
|
||||
return {
|
||||
groups:
|
||||
fields.length > 0
|
||||
? [
|
||||
{
|
||||
id: `${viewId}-ungrouped`,
|
||||
name: '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
fields,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
displayMode: 'inline',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
groups: filterDraftGroupsForDisplay(
|
||||
buildDefaultFieldsWidgetGroups({
|
||||
fields: objectMetadataItem.fields,
|
||||
objectNameSingular,
|
||||
labelIdentifierFieldMetadataItemId:
|
||||
labelIdentifierFieldMetadataItem?.id,
|
||||
}),
|
||||
),
|
||||
displayMode: 'grouped',
|
||||
};
|
||||
return filterDraftGroupsForDisplay(
|
||||
buildDefaultFieldsWidgetGroups({
|
||||
fields: objectMetadataItem.fields,
|
||||
objectNameSingular,
|
||||
labelIdentifierFieldMetadataItemId:
|
||||
labelIdentifierFieldMetadataItem?.id,
|
||||
}),
|
||||
);
|
||||
}, [
|
||||
objectMetadataItem,
|
||||
objectNameSingular,
|
||||
labelIdentifierFieldMetadataItem,
|
||||
view,
|
||||
viewId,
|
||||
]);
|
||||
|
||||
const displayMode: FieldsWidgetDisplayMode = 'grouped';
|
||||
|
||||
return {
|
||||
groups,
|
||||
displayMode,
|
||||
isFromView:
|
||||
isDefined(view) &&
|
||||
(isNonEmptyArray(view.viewFieldGroups) ||
|
||||
isNonEmptyArray(view.viewFields)),
|
||||
isFromView: isDefined(view) && isNonEmptyArray(view.viewFieldGroups),
|
||||
};
|
||||
};
|
||||
|
||||
+3
-3
@@ -29,7 +29,7 @@ export const useSaveRecordTableWidgetFiltersToView = (
|
||||
const {
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterGroupAPIDelete,
|
||||
} = usePerformViewFilterGroupAPIPersist();
|
||||
|
||||
const currentRecordFiltersCallbackState = useAtomComponentStateCallbackState(
|
||||
@@ -142,7 +142,7 @@ export const useSaveRecordTableWidgetFiltersToView = (
|
||||
})),
|
||||
);
|
||||
|
||||
await performViewFilterGroupAPIDestroy(
|
||||
await performViewFilterGroupAPIDelete(
|
||||
viewFilterGroupsToDelete.map((viewFilterGroup) => viewFilterGroup.id),
|
||||
);
|
||||
}, [
|
||||
@@ -155,7 +155,7 @@ export const useSaveRecordTableWidgetFiltersToView = (
|
||||
performViewFilterAPIDelete,
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterGroupAPIDelete,
|
||||
]);
|
||||
|
||||
return { saveRecordTableWidgetFiltersToView };
|
||||
|
||||
+3
-3
@@ -39,7 +39,7 @@ export const useSaveRecordTableWidgetsViewDataOnDashboardSave = () => {
|
||||
const {
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterGroupAPIDelete,
|
||||
} = usePerformViewFilterGroupAPIPersist();
|
||||
|
||||
const {
|
||||
@@ -251,7 +251,7 @@ export const useSaveRecordTableWidgetsViewDataOnDashboardSave = () => {
|
||||
},
|
||||
})),
|
||||
);
|
||||
await performViewFilterGroupAPIDestroy(
|
||||
await performViewFilterGroupAPIDelete(
|
||||
viewFilterGroupsToDelete.map((viewFilterGroup) => viewFilterGroup.id),
|
||||
);
|
||||
|
||||
@@ -297,7 +297,7 @@ export const useSaveRecordTableWidgetsViewDataOnDashboardSave = () => {
|
||||
performViewFilterAPIDelete,
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterGroupAPIDelete,
|
||||
performViewSortAPICreate,
|
||||
performViewSortAPIUpdate,
|
||||
performViewSortAPIDelete,
|
||||
|
||||
-2
@@ -10,7 +10,6 @@ const buildViewField = (
|
||||
id: v4(),
|
||||
fieldMetadataId: v4(),
|
||||
position: 0,
|
||||
isActive: true,
|
||||
isVisible: true,
|
||||
size: 100,
|
||||
aggregateOperation: null,
|
||||
@@ -21,7 +20,6 @@ const buildExistingViewField = (overrides: Partial<ViewField>): ViewField => ({
|
||||
id: v4(),
|
||||
fieldMetadataId: v4(),
|
||||
position: 0,
|
||||
isActive: true,
|
||||
isVisible: true,
|
||||
size: 100,
|
||||
aggregateOperation: null,
|
||||
|
||||
+5
-17
@@ -1,20 +1,14 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { type WidgetCardVariant } from '~/modules/page-layout/widgets/types/WidgetCardVariant';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WidgetCardContentStyledProps = {
|
||||
variant: WidgetCardVariant;
|
||||
hasHeader: boolean;
|
||||
isEditable: boolean;
|
||||
isInVerticalListTab: boolean;
|
||||
isMobile: boolean;
|
||||
};
|
||||
|
||||
const StyledWidgetCardContent = styled.div<WidgetCardContentStyledProps>`
|
||||
background-color: ${({ variant, isInVerticalListTab, isMobile }) =>
|
||||
variant === 'record-page' && isInVerticalListTab && !isMobile
|
||||
? themeCssVariables.background.secondary
|
||||
: 'transparent'};
|
||||
border: ${({ variant, isEditable }) =>
|
||||
variant === 'record-page' || (variant === 'side-column' && isEditable)
|
||||
? `1px solid ${themeCssVariables.border.color.medium}`
|
||||
@@ -46,10 +40,10 @@ const StyledWidgetCardContent = styled.div<WidgetCardContentStyledProps>`
|
||||
}};
|
||||
|
||||
&:empty {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
margin-top: ${({ hasHeader, variant, isEditable }) => {
|
||||
if (hasHeader && variant === 'side-column' && !isEditable) return '0';
|
||||
return hasHeader ? themeCssVariables.spacing[2] : '0';
|
||||
}};
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -57,8 +51,6 @@ type WidgetCardContentProps = {
|
||||
variant: WidgetCardVariant;
|
||||
hasHeader: boolean;
|
||||
isEditable: boolean;
|
||||
isInVerticalListTab: boolean;
|
||||
isMobile: boolean;
|
||||
hasInteractiveContent?: boolean;
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
@@ -68,8 +60,6 @@ export const WidgetCardContent = ({
|
||||
variant,
|
||||
hasHeader,
|
||||
isEditable,
|
||||
isInVerticalListTab,
|
||||
isMobile,
|
||||
hasInteractiveContent = false,
|
||||
className,
|
||||
children,
|
||||
@@ -87,8 +77,6 @@ export const WidgetCardContent = ({
|
||||
variant={variant}
|
||||
hasHeader={hasHeader}
|
||||
isEditable={isEditable}
|
||||
isInVerticalListTab={isInVerticalListTab}
|
||||
isMobile={isMobile}
|
||||
className={className}
|
||||
onClick={handleContentClick}
|
||||
>
|
||||
|
||||
+25
-1
@@ -10,10 +10,13 @@ import { addWidgetToTab } from '@/page-layout/utils/addWidgetToTab';
|
||||
import { createDefaultFieldWidget } from '@/page-layout/utils/createDefaultFieldWidget';
|
||||
import { createDefaultFieldsWidget } from '@/page-layout/utils/createDefaultFieldsWidget';
|
||||
import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord';
|
||||
import { getWidgetConfigurationViewId } from '@/page-layout/utils/getWidgetConfigurationViewId';
|
||||
import { isVerticalListPosition } from '@/page-layout/utils/isVerticalListPosition';
|
||||
import { removeWidgetFromTab } from '@/page-layout/utils/removeWidgetFromTab';
|
||||
import { useFieldWidgetEligibleFields } from '@/page-layout/widgets/field/hooks/useFieldWidgetEligibleFields';
|
||||
import { getFieldWidgetDefaultDisplayMode } from '@/page-layout/widgets/field/utils/getFieldWidgetDisplayModeConfig';
|
||||
import { useDeleteViewForFieldsWidget } from '@/page-layout/widgets/fields/hooks/useDeleteViewForFieldsWidget';
|
||||
import { useDeleteViewForRecordTableWidget } from '@/page-layout/widgets/record-table/hooks/useDeleteViewForRecordTableWidget';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
@@ -88,6 +91,11 @@ export const SidePanelPageLayoutRecordPageWidgetTypeSelect = () => {
|
||||
const { insertCreatedWidgetAtContext } =
|
||||
useInsertCreatedWidgetAtContext(pageLayoutId);
|
||||
|
||||
const { deleteViewForFieldsWidget } = useDeleteViewForFieldsWidget();
|
||||
|
||||
const { deleteViewForRecordTableWidget } =
|
||||
useDeleteViewForRecordTableWidget();
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: targetObjectNameSingular,
|
||||
});
|
||||
@@ -134,11 +142,28 @@ export const SidePanelPageLayoutRecordPageWidgetTypeSelect = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDefined(existingWidget)) {
|
||||
const viewId = getWidgetConfigurationViewId(existingWidget.configuration);
|
||||
|
||||
if (isDefined(viewId)) {
|
||||
if (existingWidget.type === WidgetType.RECORD_TABLE) {
|
||||
deleteViewForRecordTableWidget(viewId);
|
||||
}
|
||||
|
||||
if (existingWidget.type === WidgetType.FIELDS) {
|
||||
deleteViewForFieldsWidget(viewId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.set(pageLayoutDraftState, (prev) => ({
|
||||
...prev,
|
||||
tabs: removeWidgetFromTab(prev.tabs, tabId, pageLayoutEditingWidgetId),
|
||||
}));
|
||||
}, [
|
||||
deleteViewForFieldsWidget,
|
||||
deleteViewForRecordTableWidget,
|
||||
existingWidget,
|
||||
isReplaceMode,
|
||||
pageLayoutDraftState,
|
||||
pageLayoutEditingWidgetId,
|
||||
@@ -303,7 +328,6 @@ export const SidePanelPageLayoutRecordPageWidgetTypeSelect = () => {
|
||||
const newWidget: PageLayoutWidget = {
|
||||
__typename: 'PageLayoutWidget',
|
||||
id: widgetId,
|
||||
isActive: true,
|
||||
pageLayoutTabId: tabId,
|
||||
title: frontComponent.name,
|
||||
type: WidgetType.FRONT_COMPONENT,
|
||||
|
||||
+39
@@ -140,6 +140,45 @@ describe('useAddressAutocomplete', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should use place street over full autocomplete text', async () => {
|
||||
const mockOnChange = jest.fn();
|
||||
|
||||
mockGetPlaceDetailsData.mockResolvedValue({
|
||||
street: '123 Main St',
|
||||
city: 'Springfield',
|
||||
state: 'IL',
|
||||
country: 'US',
|
||||
postcode: '62704',
|
||||
});
|
||||
mockFindCountryNameByCountryCode.mockReturnValue('United States');
|
||||
|
||||
const { result } = renderHook(() => useAddressAutocomplete(mockOnChange));
|
||||
|
||||
await act(async () => {
|
||||
await result.current.autoFillInputsFromPlaceDetails(
|
||||
'place123',
|
||||
'token123',
|
||||
'123 Main St, Springfield, IL 62704, USA',
|
||||
{
|
||||
addressStreet1: '',
|
||||
addressStreet2: null,
|
||||
addressCity: null,
|
||||
addressState: null,
|
||||
addressCountry: null,
|
||||
addressPostcode: null,
|
||||
addressLat: null,
|
||||
addressLng: null,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockOnChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
addressStreet1: '123 Main St',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should preserve existing values when place data is missing', async () => {
|
||||
const mockOnChange = jest.fn();
|
||||
const mockPlaceData = {
|
||||
|
||||
@@ -80,7 +80,10 @@ export const useAddressAutocomplete = (
|
||||
const countryName = findCountryNameByCountryCode(placeData?.country);
|
||||
|
||||
const updatedAddress = {
|
||||
addressStreet1: addressStreet1 || (internalValue?.addressStreet1 ?? ''),
|
||||
addressStreet1:
|
||||
placeData?.street ||
|
||||
addressStreet1 ||
|
||||
(internalValue?.addressStreet1 ?? ''),
|
||||
addressStreet2: internalValue?.addressStreet2 ?? null,
|
||||
addressCity: placeData?.city || (internalValue?.addressCity ?? null),
|
||||
addressState: placeData?.state || (internalValue?.addressState ?? null),
|
||||
|
||||
@@ -10,7 +10,6 @@ export const VIEW_FIELD_FRAGMENT = gql`
|
||||
size
|
||||
aggregateOperation
|
||||
viewFieldGroupId
|
||||
isActive
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
|
||||
@@ -9,7 +9,6 @@ export const VIEW_FIELD_GROUP_FRAGMENT = gql`
|
||||
position
|
||||
isVisible
|
||||
viewId
|
||||
isActive
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
|
||||
+5
-5
@@ -104,11 +104,11 @@ export const usePerformViewFilterGroupAPIPersist = () => {
|
||||
[apolloClient],
|
||||
);
|
||||
|
||||
const performViewFilterGroupAPIDestroy = useCallback(
|
||||
(viewFilterGroupIdsToDestroy: string[]) => {
|
||||
if (!viewFilterGroupIdsToDestroy.length) return;
|
||||
const performViewFilterGroupAPIDelete = useCallback(
|
||||
(viewFilterGroupIdsToDelete: string[]) => {
|
||||
if (!viewFilterGroupIdsToDelete.length) return;
|
||||
return Promise.all(
|
||||
viewFilterGroupIdsToDestroy.map((viewFilterGroupId) =>
|
||||
viewFilterGroupIdsToDelete.map((viewFilterGroupId) =>
|
||||
apolloClient.mutate<{ destroyViewFilterGroup: ViewFilterGroup }>({
|
||||
mutation: DESTROY_VIEW_FILTER_GROUP,
|
||||
variables: {
|
||||
@@ -124,6 +124,6 @@ export const usePerformViewFilterGroupAPIPersist = () => {
|
||||
return {
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterGroupAPIDelete,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { useSaveAnyFieldFilterToView } from '@/views/hooks/useSaveAnyFieldFilterToView';
|
||||
import { useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters } from '@/views/hooks/useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters';
|
||||
import { useSaveRecordFilterGroupsToViewFilterGroups } from '@/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups';
|
||||
import { useSaveRecordFiltersToViewFilters } from '@/views/hooks/useSaveRecordFiltersToViewFilters';
|
||||
import { useSaveRecordSortsToViewSorts } from '@/views/hooks/useSaveRecordSortsToViewSorts';
|
||||
|
||||
export const useSaveCurrentViewFiltersAndSorts = () => {
|
||||
const { saveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters } =
|
||||
useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters();
|
||||
const { saveRecordFilterGroupsToViewFilterGroups } =
|
||||
useSaveRecordFilterGroupsToViewFilterGroups();
|
||||
|
||||
const { saveRecordFiltersToViewFilters } =
|
||||
useSaveRecordFiltersToViewFilters();
|
||||
|
||||
const { saveRecordSortsToViewSorts } = useSaveRecordSortsToViewSorts();
|
||||
|
||||
@@ -12,7 +16,8 @@ export const useSaveCurrentViewFiltersAndSorts = () => {
|
||||
|
||||
const saveCurrentViewFilterAndSorts = async () => {
|
||||
await saveRecordSortsToViewSorts();
|
||||
await saveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters();
|
||||
await saveRecordFilterGroupsToViewFilterGroups();
|
||||
await saveRecordFiltersToViewFilters();
|
||||
await saveAnyFieldFilterToView();
|
||||
};
|
||||
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { usePerformViewFilterGroupAPIPersist } from '@/views/hooks/internal/usePerformViewFilterGroupAPIPersist';
|
||||
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { getViewFilterGroupsToCreate } from '@/views/utils/getViewFilterGroupsToCreate';
|
||||
import { getViewFilterGroupsToDelete } from '@/views/utils/getViewFilterGroupsToDelete';
|
||||
import { getViewFilterGroupsToUpdate } from '@/views/utils/getViewFilterGroupsToUpdate';
|
||||
import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useSaveRecordFilterGroupsToViewFilterGroups = () => {
|
||||
const { canPersistChanges } = useCanPersistViewChanges();
|
||||
const {
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDelete,
|
||||
} = usePerformViewFilterGroupAPIPersist();
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
|
||||
const currentRecordFilterGroupsCallbackState =
|
||||
useAtomComponentStateCallbackState(currentRecordFilterGroupsComponentState);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const saveRecordFilterGroupsToViewFilterGroups = useCallback(async () => {
|
||||
if (!canPersistChanges || !isDefined(currentView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentViewFilterGroups = currentView?.viewFilterGroups ?? [];
|
||||
|
||||
const currentRecordFilterGroups = store.get(
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
);
|
||||
|
||||
const newViewFilterGroups = currentRecordFilterGroups.map(
|
||||
(recordFilterGroup) =>
|
||||
mapRecordFilterGroupToViewFilterGroup({
|
||||
recordFilterGroup,
|
||||
view: currentView,
|
||||
}),
|
||||
);
|
||||
|
||||
const viewFilterGroupsToCreate = getViewFilterGroupsToCreate(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupsToDelete = getViewFilterGroupsToDelete(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupsToUpdate = getViewFilterGroupsToUpdate(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupIdsToDelete = viewFilterGroupsToDelete.map(
|
||||
(viewFilterGroup) => viewFilterGroup.id,
|
||||
);
|
||||
|
||||
await performViewFilterGroupAPICreate(
|
||||
viewFilterGroupsToCreate,
|
||||
currentView,
|
||||
);
|
||||
await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
|
||||
await performViewFilterGroupAPIDelete(viewFilterGroupIdsToDelete);
|
||||
}, [
|
||||
canPersistChanges,
|
||||
currentView,
|
||||
store,
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDelete,
|
||||
]);
|
||||
|
||||
return {
|
||||
saveRecordFilterGroupsToViewFilterGroups,
|
||||
};
|
||||
};
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
|
||||
import { type FlatViewFilter } from '@/metadata-store/types/FlatViewFilter';
|
||||
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
|
||||
import { usePerformViewFilterGroupAPIPersist } from '@/views/hooks/internal/usePerformViewFilterGroupAPIPersist';
|
||||
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { getViewFilterGroupsToCreate } from '@/views/utils/getViewFilterGroupsToCreate';
|
||||
import { getViewFilterGroupsToDelete } from '@/views/utils/getViewFilterGroupsToDelete';
|
||||
import { getViewFilterGroupsToUpdate } from '@/views/utils/getViewFilterGroupsToUpdate';
|
||||
import { getViewFiltersToCreate } from '@/views/utils/getViewFiltersToCreate';
|
||||
import { getViewFiltersToDelete } from '@/views/utils/getViewFiltersToDelete';
|
||||
import { getViewFiltersToUpdate } from '@/views/utils/getViewFiltersToUpdate';
|
||||
import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup';
|
||||
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters =
|
||||
() => {
|
||||
const { canPersistChanges } = useCanPersistViewChanges();
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const {
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
} = usePerformViewFilterGroupAPIPersist();
|
||||
|
||||
const {
|
||||
performViewFilterAPICreate,
|
||||
performViewFilterAPIUpdate,
|
||||
performViewFilterAPIDestroy,
|
||||
} = usePerformViewFilterAPIPersist();
|
||||
|
||||
const currentRecordFilterGroupsCallbackState =
|
||||
useAtomComponentStateCallbackState(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFiltersCallbackState =
|
||||
useAtomComponentStateCallbackState(currentRecordFiltersComponentState);
|
||||
|
||||
const saveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters =
|
||||
useCallback(async () => {
|
||||
if (!canPersistChanges || !isDefined(currentView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentViewFilterGroups = currentView.viewFilterGroups ?? [];
|
||||
const currentRecordFilterGroups = store.get(
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
);
|
||||
|
||||
const newViewFilterGroups = currentRecordFilterGroups.map(
|
||||
(recordFilterGroup) =>
|
||||
mapRecordFilterGroupToViewFilterGroup({
|
||||
recordFilterGroup,
|
||||
view: currentView,
|
||||
}),
|
||||
);
|
||||
|
||||
const viewFilterGroupsToCreate = getViewFilterGroupsToCreate(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupsToDelete = getViewFilterGroupsToDelete(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupsToUpdate = getViewFilterGroupsToUpdate(
|
||||
currentViewFilterGroups,
|
||||
newViewFilterGroups,
|
||||
);
|
||||
|
||||
const viewFilterGroupIdsToDestroy = viewFilterGroupsToDelete.map(
|
||||
(viewFilterGroup) => viewFilterGroup.id,
|
||||
);
|
||||
|
||||
await performViewFilterGroupAPICreate(
|
||||
viewFilterGroupsToCreate,
|
||||
currentView,
|
||||
);
|
||||
await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
|
||||
await performViewFilterGroupAPIDestroy(viewFilterGroupIdsToDestroy);
|
||||
|
||||
// Mirror the DB cascade: remove cascade-deleted viewFilters from the store
|
||||
if (viewFilterGroupIdsToDestroy.length > 0) {
|
||||
const destroyedIdsSet = new Set(viewFilterGroupIdsToDestroy);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('viewFilters'), (prev) => ({
|
||||
...prev,
|
||||
current: (prev.current as FlatViewFilter[]).filter(
|
||||
(viewFilter) =>
|
||||
!isDefined(viewFilter.viewFilterGroupId) ||
|
||||
!destroyedIdsSet.has(viewFilter.viewFilterGroupId),
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
const currentViewFilters = currentView.viewFilters ?? [];
|
||||
const currentRecordFilters = store.get(
|
||||
currentRecordFiltersCallbackState,
|
||||
);
|
||||
|
||||
const newViewFilters = currentRecordFilters.map(
|
||||
mapRecordFilterToViewFilter,
|
||||
);
|
||||
|
||||
const viewFiltersToCreate = getViewFiltersToCreate(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
);
|
||||
|
||||
const viewFiltersToDelete = getViewFiltersToDelete(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
).filter(
|
||||
(viewFilter) =>
|
||||
!isDefined(viewFilter.viewFilterGroupId) ||
|
||||
!viewFilterGroupIdsToDestroy.includes(viewFilter.viewFilterGroupId),
|
||||
);
|
||||
|
||||
const viewFiltersToUpdate = getViewFiltersToUpdate(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
);
|
||||
|
||||
const createViewFilterInputs = viewFiltersToCreate.map(
|
||||
(viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
fieldMetadataId: viewFilter.fieldMetadataId,
|
||||
viewId: currentView.id,
|
||||
value: viewFilter.value,
|
||||
operand: viewFilter.operand,
|
||||
viewFilterGroupId: viewFilter.viewFilterGroupId,
|
||||
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
|
||||
subFieldName: viewFilter.subFieldName ?? null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const updateViewFilterInputs = viewFiltersToUpdate.map(
|
||||
(viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
update: {
|
||||
value: viewFilter.value,
|
||||
operand: viewFilter.operand,
|
||||
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
|
||||
viewFilterGroupId: viewFilter.viewFilterGroupId,
|
||||
subFieldName: viewFilter.subFieldName ?? null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const destroyViewFilterInputs = viewFiltersToDelete.map(
|
||||
(viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const createResult = await performViewFilterAPICreate(
|
||||
createViewFilterInputs,
|
||||
);
|
||||
if (createResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateResult = await performViewFilterAPIUpdate(
|
||||
updateViewFilterInputs,
|
||||
);
|
||||
if (updateResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const deleteResult = await performViewFilterAPIDestroy(
|
||||
destroyViewFilterInputs,
|
||||
);
|
||||
if (deleteResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
}, [
|
||||
canPersistChanges,
|
||||
currentView,
|
||||
store,
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
currentRecordFiltersCallbackState,
|
||||
performViewFilterGroupAPICreate,
|
||||
performViewFilterGroupAPIUpdate,
|
||||
performViewFilterGroupAPIDestroy,
|
||||
performViewFilterAPICreate,
|
||||
performViewFilterAPIUpdate,
|
||||
performViewFilterAPIDestroy,
|
||||
]);
|
||||
|
||||
return {
|
||||
saveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,137 @@
|
||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
|
||||
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
|
||||
import { viewsSelector } from '@/views/states/selectors/viewsSelector';
|
||||
import { getViewFiltersToCreate } from '@/views/utils/getViewFiltersToCreate';
|
||||
import { getViewFiltersToDelete } from '@/views/utils/getViewFiltersToDelete';
|
||||
import { getViewFiltersToUpdate } from '@/views/utils/getViewFiltersToUpdate';
|
||||
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useSaveRecordFiltersToViewFilters = () => {
|
||||
const { canPersistChanges } = useCanPersistViewChanges();
|
||||
const {
|
||||
performViewFilterAPICreate,
|
||||
performViewFilterAPIUpdate,
|
||||
performViewFilterAPIDelete,
|
||||
} = usePerformViewFilterAPIPersist();
|
||||
|
||||
const contextStoreCurrentViewId = useAtomComponentStateValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFiltersCallbackState = useAtomComponentStateCallbackState(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const saveRecordFiltersToViewFilters = useCallback(async () => {
|
||||
const views = store.get(viewsSelector.atom);
|
||||
|
||||
const currentView = views.find(
|
||||
(view) => view.id === contextStoreCurrentViewId,
|
||||
);
|
||||
|
||||
if (!isDefined(currentView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canPersistChanges || !isDefined(currentView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentViewFilters = currentView?.viewFilters ?? [];
|
||||
|
||||
const currentRecordFilters = store.get(currentRecordFiltersCallbackState);
|
||||
|
||||
const newViewFilters = currentRecordFilters.map(
|
||||
mapRecordFilterToViewFilter,
|
||||
);
|
||||
|
||||
const viewFiltersToCreate = getViewFiltersToCreate(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
);
|
||||
|
||||
const viewFiltersToDelete = getViewFiltersToDelete(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
);
|
||||
|
||||
const viewFiltersToUpdate = getViewFiltersToUpdate(
|
||||
currentViewFilters,
|
||||
newViewFilters,
|
||||
);
|
||||
|
||||
const createViewFilterInputs = viewFiltersToCreate.map((viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
fieldMetadataId: viewFilter.fieldMetadataId,
|
||||
viewId: currentView.id,
|
||||
value: viewFilter.value,
|
||||
operand: viewFilter.operand,
|
||||
viewFilterGroupId: viewFilter.viewFilterGroupId,
|
||||
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
|
||||
subFieldName: viewFilter.subFieldName ?? null,
|
||||
},
|
||||
}));
|
||||
|
||||
const updateViewFilterInputs = viewFiltersToUpdate.map((viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
update: {
|
||||
value: viewFilter.value,
|
||||
operand: viewFilter.operand,
|
||||
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
|
||||
viewFilterGroupId: viewFilter.viewFilterGroupId,
|
||||
subFieldName: viewFilter.subFieldName ?? null,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const deleteViewFilterInputs = viewFiltersToDelete.map((viewFilter) => ({
|
||||
input: {
|
||||
id: viewFilter.id,
|
||||
},
|
||||
}));
|
||||
|
||||
const createResult = await performViewFilterAPICreate(
|
||||
createViewFilterInputs,
|
||||
);
|
||||
if (createResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateResult = await performViewFilterAPIUpdate(
|
||||
updateViewFilterInputs,
|
||||
);
|
||||
if (updateResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const deleteResult = await performViewFilterAPIDelete(
|
||||
deleteViewFilterInputs,
|
||||
);
|
||||
if (deleteResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
}, [
|
||||
store,
|
||||
canPersistChanges,
|
||||
currentRecordFiltersCallbackState,
|
||||
performViewFilterAPICreate,
|
||||
performViewFilterAPIUpdate,
|
||||
performViewFilterAPIDelete,
|
||||
contextStoreCurrentViewId,
|
||||
]);
|
||||
|
||||
return {
|
||||
saveRecordFiltersToViewFilters,
|
||||
};
|
||||
};
|
||||
@@ -16,7 +16,7 @@ export const useSaveRecordSortsToViewSorts = () => {
|
||||
const {
|
||||
performViewSortAPICreate,
|
||||
performViewSortAPIUpdate,
|
||||
performViewSortAPIDestroy,
|
||||
performViewSortAPIDelete,
|
||||
} = usePerformViewSortAPIPersist();
|
||||
|
||||
const { currentView } = useGetCurrentViewOnly();
|
||||
@@ -71,7 +71,7 @@ export const useSaveRecordSortsToViewSorts = () => {
|
||||
},
|
||||
}));
|
||||
|
||||
const destroyViewSortInputs = viewSortsToDelete.map((viewSort) => ({
|
||||
const deleteViewSortInputs = viewSortsToDelete.map((viewSort) => ({
|
||||
input: {
|
||||
id: viewSort.id,
|
||||
},
|
||||
@@ -87,7 +87,7 @@ export const useSaveRecordSortsToViewSorts = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const deleteResult = await performViewSortAPIDestroy(destroyViewSortInputs);
|
||||
const deleteResult = await performViewSortAPIDelete(deleteViewSortInputs);
|
||||
if (deleteResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
@@ -98,7 +98,7 @@ export const useSaveRecordSortsToViewSorts = () => {
|
||||
currentRecordSortsCallbackState,
|
||||
performViewSortAPICreate,
|
||||
performViewSortAPIUpdate,
|
||||
performViewSortAPIDestroy,
|
||||
performViewSortAPIDelete,
|
||||
]);
|
||||
|
||||
return {
|
||||
|
||||
@@ -24,7 +24,7 @@ export const viewsSelector = createAtomSelector<ViewWithRelations[]>({
|
||||
flatObjectMetadataItems.map((item) => [item.id, item]),
|
||||
);
|
||||
|
||||
const allFlatViewFields = get(metadataStoreState, 'viewFields')
|
||||
const flatViewFields = get(metadataStoreState, 'viewFields')
|
||||
.current as FlatViewField[];
|
||||
const flatViewFilters = get(metadataStoreState, 'viewFilters')
|
||||
.current as FlatViewFilter[];
|
||||
@@ -34,14 +34,9 @@ export const viewsSelector = createAtomSelector<ViewWithRelations[]>({
|
||||
.current as FlatViewGroup[];
|
||||
const flatViewFilterGroups = get(metadataStoreState, 'viewFilterGroups')
|
||||
.current as FlatViewFilterGroup[];
|
||||
const allFlatViewFieldGroups = get(metadataStoreState, 'viewFieldGroups')
|
||||
const flatViewFieldGroups = get(metadataStoreState, 'viewFieldGroups')
|
||||
.current as FlatViewFieldGroup[];
|
||||
|
||||
const flatViewFields = allFlatViewFields.filter((field) => field.isActive);
|
||||
const flatViewFieldGroups = allFlatViewFieldGroups.filter(
|
||||
(group) => group.isActive,
|
||||
);
|
||||
|
||||
const viewFieldsByViewId = new Map<string, FlatViewField[]>();
|
||||
const viewFiltersByViewId = new Map<string, FlatViewFilter[]>();
|
||||
const viewSortsByViewId = new Map<string, FlatViewSort[]>();
|
||||
|
||||
@@ -8,7 +8,6 @@ export type ViewField = {
|
||||
viewId?: string;
|
||||
fieldMetadataId: string;
|
||||
position: number;
|
||||
isActive: boolean;
|
||||
isVisible: boolean;
|
||||
size: number;
|
||||
aggregateOperation?: AggregateOperations | null;
|
||||
|
||||
@@ -4,7 +4,6 @@ export type ViewFieldGroup = {
|
||||
id: string;
|
||||
name: string;
|
||||
position: number;
|
||||
isActive: boolean;
|
||||
isVisible: boolean;
|
||||
viewId: string;
|
||||
viewFields: ViewField[];
|
||||
|
||||
@@ -60,7 +60,6 @@ describe('mapViewFieldsToColumnDefinitions', () => {
|
||||
position: 1,
|
||||
size: 1,
|
||||
isVisible: false,
|
||||
isActive: true,
|
||||
definition: {
|
||||
fieldMetadataId: '1',
|
||||
label: 'label 1',
|
||||
@@ -79,7 +78,6 @@ describe('mapViewFieldsToColumnDefinitions', () => {
|
||||
position: 2,
|
||||
size: 2,
|
||||
isVisible: false,
|
||||
isActive: true,
|
||||
definition: {
|
||||
fieldMetadataId: '2',
|
||||
label: 'label 2',
|
||||
@@ -98,7 +96,6 @@ describe('mapViewFieldsToColumnDefinitions', () => {
|
||||
position: 3,
|
||||
size: 3,
|
||||
isVisible: true,
|
||||
isActive: true,
|
||||
definition: {
|
||||
fieldMetadataId: '3',
|
||||
label: 'label 3',
|
||||
@@ -191,7 +188,6 @@ describe('mapColumnDefinitionsToViewFields', () => {
|
||||
fieldMetadataId: 1,
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
isActive: true,
|
||||
definition: columnDefinitions[0],
|
||||
size: undefined,
|
||||
},
|
||||
@@ -201,7 +197,6 @@ describe('mapColumnDefinitionsToViewFields', () => {
|
||||
position: 2,
|
||||
size: 200,
|
||||
isVisible: false,
|
||||
isActive: true,
|
||||
definition: columnDefinitions[1],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -12,7 +12,6 @@ export const mapBoardFieldDefinitionsToViewFields = (
|
||||
size: 0,
|
||||
position: fieldDefinition.position,
|
||||
isVisible: fieldDefinition.isVisible ?? true,
|
||||
isActive: true,
|
||||
definition: fieldDefinition,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -12,7 +12,6 @@ export const mapColumnDefinitionsToViewFields = (
|
||||
position: columnDefinition.position,
|
||||
size: columnDefinition.size,
|
||||
isVisible: columnDefinition.isVisible ?? true,
|
||||
isActive: true,
|
||||
definition: columnDefinition,
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ export const mapRecordFieldToViewField = (recordField: RecordField) => {
|
||||
id: recordField.id,
|
||||
fieldMetadataId: recordField.fieldMetadataItemId,
|
||||
isVisible: recordField.isVisible,
|
||||
isActive: true,
|
||||
position: recordField.position,
|
||||
size: recordField.size,
|
||||
aggregateOperation: recordField.aggregateOperation,
|
||||
|
||||
@@ -133,5 +133,4 @@ export const createTestWidget = (
|
||||
updatedAt: '2024-01-01',
|
||||
deletedAt: null,
|
||||
...overrides,
|
||||
isActive: overrides.isActive ?? true,
|
||||
});
|
||||
|
||||
+2
@@ -3,6 +3,7 @@ import { type INestApplication } from '@nestjs/common';
|
||||
import 'jest';
|
||||
import { type DataSource } from 'typeorm';
|
||||
|
||||
import { type DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command';
|
||||
import { type DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
|
||||
declare module '@jest/types' {
|
||||
@@ -35,6 +36,7 @@ declare global {
|
||||
var testDataSource: DataSource;
|
||||
var app: INestApplication;
|
||||
var dataSourceService: DataSourceService;
|
||||
var dataSeedWorkspaceCommand: DataSeedWorkspaceCommand;
|
||||
}
|
||||
|
||||
export {};
|
||||
|
||||
@@ -4,10 +4,7 @@ import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import {
|
||||
SEED_APPLE_WORKSPACE_ID,
|
||||
SEED_EMPTY_WORKSPACE_3_ID,
|
||||
SEED_EMPTY_WORKSPACE_4_ID,
|
||||
SEED_YCOMBINATOR_WORKSPACE_ID,
|
||||
SeededEmptyWorkspacesIds,
|
||||
SeededWorkspacesIds,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/core/constants/seeder-workspaces.constant';
|
||||
import { DevSeederService } from 'src/engine/workspace-manager/dev-seeder/services/dev-seeder.service';
|
||||
@@ -45,21 +42,12 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
|
||||
? [SEED_APPLE_WORKSPACE_ID]
|
||||
: [SEED_APPLE_WORKSPACE_ID, SEED_YCOMBINATOR_WORKSPACE_ID];
|
||||
|
||||
const emptyWorkspaceIds: SeededEmptyWorkspacesIds[] = [
|
||||
SEED_EMPTY_WORKSPACE_3_ID,
|
||||
SEED_EMPTY_WORKSPACE_4_ID,
|
||||
];
|
||||
|
||||
try {
|
||||
for (const workspaceId of workspaceIds) {
|
||||
await this.devSeederService.seedDev(workspaceId, {
|
||||
light: options.light,
|
||||
});
|
||||
}
|
||||
|
||||
for (const workspaceId of emptyWorkspaceIds) {
|
||||
await this.devSeederService.seedEmptyWorkspace(workspaceId);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
this.logger.error(error.stack);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { InstanceCommandGenerationService } from 'src/database/commands/instance
|
||||
import { ListOrphanedWorkspaceEntitiesCommand } from 'src/database/commands/list-and-delete-orphaned-workspace-entities.command';
|
||||
import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question';
|
||||
import { RunInstanceCommandsCommand } from 'src/database/commands/run-instance-commands.command';
|
||||
import { InstanceCommandProviderModule } from 'src/database/commands/upgrade-version-command/instance-command-provider.module';
|
||||
import { UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/upgrade-version-command.module';
|
||||
import { WorkspaceExportModule } from 'src/database/commands/workspace-export/workspace-export.module';
|
||||
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||
@@ -44,6 +45,7 @@ import { AutomatedTriggerModule } from 'src/modules/workflow/workflow-trigger/au
|
||||
@Module({
|
||||
imports: [
|
||||
UpgradeVersionCommandModule,
|
||||
InstanceCommandProviderModule,
|
||||
TypeOrmModule.forFeature([WorkspaceEntity]),
|
||||
WorkspaceExportModule,
|
||||
// Cron command dependencies
|
||||
|
||||
@@ -62,9 +62,6 @@ export class RunInstanceCommandsCommand extends CommandRunner {
|
||||
await this.checkWorkspaceVersionSafety(options);
|
||||
await this.runLegacyPendingTypeOrmMigrations();
|
||||
|
||||
const activeOrSuspendedWorkspaceIds =
|
||||
await this.workspaceVersionService.getActiveOrSuspendedWorkspaceIds();
|
||||
|
||||
for (const {
|
||||
command,
|
||||
name,
|
||||
@@ -82,6 +79,9 @@ export class RunInstanceCommandsCommand extends CommandRunner {
|
||||
}
|
||||
|
||||
if (options.includeSlow) {
|
||||
const hasWorkspaces =
|
||||
await this.workspaceVersionService.hasActiveOrSuspendedWorkspaces();
|
||||
|
||||
for (const {
|
||||
command,
|
||||
name,
|
||||
@@ -90,7 +90,7 @@ export class RunInstanceCommandsCommand extends CommandRunner {
|
||||
await this.instanceUpgradeService.runSlowInstanceCommand({
|
||||
command,
|
||||
name,
|
||||
skipDataMigration: activeOrSuspendedWorkspaceIds.length === 0,
|
||||
skipDataMigration: !hasWorkspaces,
|
||||
});
|
||||
|
||||
if (result.status === 'failed') {
|
||||
@@ -119,10 +119,10 @@ export class RunInstanceCommandsCommand extends CommandRunner {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeOrSuspendedWorkspaceIds =
|
||||
const activeWorkspaceIds =
|
||||
await this.workspaceVersionService.getActiveOrSuspendedWorkspaceIds();
|
||||
|
||||
if (activeOrSuspendedWorkspaceIds.length === 0) {
|
||||
if (activeWorkspaceIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ export class RunInstanceCommandsCommand extends CommandRunner {
|
||||
const allAtPreviousVersion =
|
||||
await this.upgradeMigrationService.areAllWorkspacesAtCommand({
|
||||
commandName: lastWorkspaceCommand.name,
|
||||
workspaceIds: activeOrSuspendedWorkspaceIds,
|
||||
workspaceIds: activeWorkspaceIds,
|
||||
});
|
||||
|
||||
if (!allAtPreviousVersion) {
|
||||
|
||||
+11
-1
@@ -1,12 +1,22 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module';
|
||||
import { V1_21_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module';
|
||||
import { V1_22_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-22/1-22-upgrade-version-command.module';
|
||||
import { V1_23_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-23/1-23-upgrade-version-command.module';
|
||||
import { UpgradeCommand } from 'src/database/commands/upgrade-version-command/upgrade.command';
|
||||
import { UpgradeModule } from 'src/engine/core-modules/upgrade/upgrade.module';
|
||||
import { WorkspaceVersionModule } from 'src/engine/workspace-manager/workspace-version/workspace-version.module';
|
||||
|
||||
@Module({
|
||||
imports: [UpgradeModule, WorkspaceVersionModule, WorkspaceIteratorModule],
|
||||
imports: [
|
||||
V1_21_UpgradeVersionCommandModule,
|
||||
V1_22_UpgradeVersionCommandModule,
|
||||
V1_23_UpgradeVersionCommandModule,
|
||||
UpgradeModule,
|
||||
WorkspaceVersionModule,
|
||||
WorkspaceIteratorModule,
|
||||
],
|
||||
providers: [UpgradeCommand],
|
||||
})
|
||||
export class UpgradeVersionCommandModule {}
|
||||
|
||||
+1
-2
@@ -269,11 +269,10 @@ export class UpgradeCommand extends CommandRunner {
|
||||
);
|
||||
|
||||
for (const workspaceId of workspacesWithoutCursor) {
|
||||
await this.upgradeMigrationService.markAsWorkspaceInitial({
|
||||
await this.upgradeMigrationService.markAsInitial({
|
||||
name: lastWorkspaceCommand.name,
|
||||
workspaceId,
|
||||
executedByVersion: '1.21.0',
|
||||
status: 'completed',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user