Compare commits

...
Author SHA1 Message Date
sonarly-bot a042d14493 fix(server): harden Lambda calls against worker clock skew
https://sonarly.com/issue/38487?type=bug

Logic-function execution failed in production worker when AWS rejected a Lambda API call with `InvalidSignatureException` due to an outdated SigV4 timestamp. This caused background logic-function jobs to fail for affected executions.

Authored by Sonarly by autonomous analysis (run 43859).
2026-05-18 20:22:08 +00:00
ce8ef261c1 Update pricing plan cards (#20614)
## Summary
- Update pricing top-card bullets to use workflow credits, keep full
customization, and show Organization-only features accurately.
- Make custom AI models self-host Organization-only and move custom
domain into the Cloud Organization card.
- Align pricing comparison rows for row-level permissions, encryption
key rotation, API call limits, custom domain availability, and self-host
custom objects/fields.

## Validation
- `lingui extract --overwrite --clean`
- `lingui compile --typescript`
- `node scripts/check-section-shape.mjs`
- `git diff --check`
- Playwright snapshot of `http://localhost:3002/pricing`

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-05-18 19:43:15 +00:00
Charles BochetandGitHub 1d3d3999e2 feat(server): upgrade-aware entity decorators for cross-version upgrades (#20686)
## What

When the same PR introduces a new core entity *and* adds a cache
provider that queries it, every workspace step from older versions that
runs before the introducing instance step hits `relation … does not
exist` — the cause of the failed [v2.6.0 staging-ci
run](https://github.com/twentyhq/twenty-infra/actions/runs/26042742000).
Same class of failure for renamed core entities and for new FK columns
hidden inside relation loads.

This PR adds **upgrade-aware entity decorators** + a runtime that adapts
TypeORM's view of the schema to the current `core.upgradeMigration`
cursor.

## Strategy

```
                    ┌────────────────────────────────┐
                    │  @Entity classes (final shape) │
                    │   + @WasIntroducedInUpgrade    │
                    │   + @WasRenamedInUpgrade       │
                    └───────────────┬────────────────┘
                                    │
              UpgradeSequenceRunner.run()
              ┌─────────────────────┴─────────────────────┐
              ▼                                           ▼
       step N+1 begins                          step N just completed
              │                                           │
              └────────► adapter.refresh() ◄──────────────┘
                            │
            reads core.upgradeMigration via
            UpgradeMigrationService.getLastAttemptedInstanceCommand
                            │
                            ▼
       ┌────────────────────────────────────────────────────────┐
       │  UpgradeAwareEntityMetadataAdapter                     │
       │  • mutates EntityMetadata.tableName / tablePath        │
       │     -> historical name for renames not yet applied     │
       │  • flips column.isSelect = false for not-yet-introduced│
       │     columns                                            │
       │  • tracks per-entity availability sidecar              │
       └─────────────────┬──────────────────────────────────────┘
                         │
                         ▼
       DataSource.getRepository wrapped at TypeOrmModule.forRoot:
       repo.find() / findOne() / count() / …
       ┌─────────────────────────────────────────┐
       │  wrapRepositoryWithUpgradeAwareProxy    │
       │  • entity unavailable -> short-circuit  │
       │     (find -> [], count -> 0,            │
       │      findOneOrFail -> EntityNotFound)   │
       │  • write -> Promise.reject(             │
       │      UpgradeUnavailableEntityWriteEx)   │
       │  • find({ relations: ['X'] }) with X    │
       │     unavailable -> X stripped           │
       └─────────────────────────────────────────┘
```

The decorator strings reference real `core.upgradeMigration.name` values
(`${version}_${className}_${timestamp}`). A boot-time validator walks
the actual `UpgradeSequenceReaderService.getUpgradeSequence()` and fails
fast on typos.

## Files

- New decorators:
`engine/core-modules/upgrade/decorators/was-introduced-in-upgrade.decorator.ts`,
`was-renamed-in-upgrade.decorator.ts`
- Runtime: `engine/twenty-orm/upgrade-aware/` (adapter, proxy, install
hook, state singleton, exceptions)
- Wired into `UpgradeSequenceRunnerService` (`refresh()` between steps)
and `TypeOrmModule.forRoot` (proxy install)
- 2-6 entity decorations: `RolePermissionFlagEntity` (rename history +
new `permissionFlagId` column), `PermissionFlagEntity` (new catalog)

## Validation

End-to-end local cross-version upgrade (v1.22 → HEAD): `28 workspace(s)
succeeded, 0 failed`; `upgrade:status → Instance: Up to date, 4 up to
date, 0 behind, 0 failed`. Full log excerpts and the
second-failure-found-and-fixed (`WorkspaceRolesPermissionsCacheService`
relation load) in [this
comment](https://github.com/twentyhq/twenty/pull/20686#issuecomment-4480036816).

## Test plan

- [x] Adapter spec covers rename mutation; proxy spec covers `find()`
short-circuit on unavailable entity. Resolver + validator + decorators
are covered by `resolve-entity-shape-at-upgrade-cursor.util.spec.ts`
(integration-level via real decorator application).
- [x] `nx lint:diff-with-main twenty-server` + `nx typecheck
twenty-server` clean
- [x] All 82 affected tests passing
- [ ] Cross-version-upgrade CI re-runs after this lands; v2.6.0 retag
once green

## Follow-ups deferred

- v2.7 `connectionProvider` rename repro as a permanent end-to-end test
artifact
- Extending the proxy to also cover `EntityManager.getRepository` and
`createQueryBuilder` if a non-`find()` upgrade-time consumer surfaces
2026-05-18 21:38:20 +02:00
EtienneandGitHub 89579f5225 fix(ai-chat) - upload files (#20681)
closes https://github.com/twentyhq/twenty/issues/20437

bonus : persist file filename for UI display
2026-05-18 15:50:02 +00:00
132d997474 i18n - translations (#20685)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-18 17:42:30 +02:00
7c252ff233 Fix 19026 deactivated relation unassignable (#19296)
PR to fix the bug #19026 

This PR will ensure that if an object has some relation deactivated, the
relation will not be visible in the side panel tab and will not be
assignable in the deactivated relation.

## Notes deactivated in People
<img width="1068" height="1106" alt="image"
src="https://github.com/user-attachments/assets/e8c2dbf3-5391-4dbc-8e40-79fcc44e8158"
/>

## Notes not visible in the side panel of people
<img width="2390" height="892" alt="image"
src="https://github.com/user-attachments/assets/308a78aa-2c6d-4d3d-b67c-b49795839aae"
/>

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2026-05-18 15:25:51 +00:00
nitinandGitHub 4ba9c0ca0b [Navigation Drawer] Multiple fixes in settings and app drawer (#20634)
closes -
https://discord.com/channels/1130383047699738754/1487720717192527942



https://github.com/user-attachments/assets/6db2df8b-be01-4b5f-a958-575d87b41559

~~waiting on @Bonapara 's feedback!~~
2026-05-18 15:22:03 +00:00
Charles BochetandGitHub d03480472c perf(server): index messageChannel/calendarChannel for per-workspace sync crons (#20678)
## Summary

The messaging/calendar import crons each iterate every active workspace
and execute one `find` per workspace against `core."messageChannel"` /
`core."calendarChannel"` with the shape:

```
WHERE "workspaceId" = $1 AND "isSyncEnabled" = true AND "syncStage" = $2 [AND "type" <> $3]
```

There is currently no index supporting that shape, so the planner does a
seq scan on each table for every iteration. On prod-eu (RDS Performance
Insights, `rds-prod-eu-one`), these two queries are the top two by load
— together ~12 AAS, ~12 calls/sec — and have been the primary
contributor to the sustained 100% CPU since active workspace count grew.

This PR adds composite indexes on `(workspaceId, isSyncEnabled,
syncStage)` for both tables as an instance migration in 2.6.0.
2026-05-18 14:31:03 +00:00
8f3c336e62 i18n - docs translations (#20680)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-18 15:37:33 +02:00
Thomas des FrancsandGitHub e7a1448414 Add OpenAI Apps domain challenge file (#20677)
## Summary
- Add the OpenAI Apps domain verification token as a static well-known
file on the Twenty website.

## Why
The OpenAI Apps submission form allows a challenge base URL on the MCP
hostname or a parent hostname. Since the MCP hostname is
`api.twenty.com`, the parent origin `https://twenty.com` can serve the
challenge at `/.well-known/openai-apps-challenge` without adding an API
route.

## Validation
- `curl -I -L https://twenty.com/.well-known/openai-apps-challenge`
currently returns 404, confirming the file is not already live.
- `git diff --check origin/main...HEAD`
- Verified the PR diff is a single static file:
`packages/twenty-website-new/public/.well-known/openai-apps-challenge`.

## Submission setting
Use `https://twenty.com` as the Challenge Base URL after this is
deployed.
2026-05-18 12:29:53 +00:00
EtienneandGitHub fc74938d7b fix(billing) - query timeout (#20669)
Sonarly context : https://sonarly.com/issue/33412
Sentry issue :
https://twenty-v7.sentry.io/issues/7454613767/?project=4507072499810304
2026-05-18 12:29:47 +00:00
Thomas des FrancsandGitHub d5e65c563e Add MCP tool annotations (#20672)
## Summary

Adds explicit MCP tool annotations for the Twenty MCP server so ChatGPT
app submission review can inspect the exposed tools without relying on
protocol defaults.

## Changes

- Adds one-export annotation constants for closed-world read-only tools,
open-world read-only tools, and `execute_tool`.
- Attaches annotations to the five exposed MCP tools:
`search_help_center`, `get_tool_catalog`, `learn_tools`, `execute_tool`,
and `load_skills`.
- Marks `search_help_center` as read-only and open-world because it
performs outbound help-center HTTP requests.
- Keeps `get_tool_catalog`, `learn_tools`, and `load_skills` read-only
and closed-world.
- Keeps `execute_tool` non-read-only, open-world, and destructive
because it can route to tools that create/update/delete records or send
email.
- Returns annotations through `tools/list` and updates MCP tests to
cover them.

No output schemas are included in this PR.

## Validation

- `git diff --check origin/main...HEAD`
- `jest --config packages/twenty-server/jest.config.mjs
packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-tool-executor.service.spec.ts
packages/twenty-server/src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts
--runInBand`

Note: the Jest command was run with arm64 Node because the available
shared `node_modules` install contains the arm64 SWC native binding.
2026-05-18 12:14:34 +00:00
5c8ddb0c12 i18n - translations (#20674)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-18 14:15:45 +02:00
db0547f503 [1/3] Rename permissionFlag to rolePermissionFlag + add permissionFlag catalog/backfill (#20481)
Split of #20377.

## Summary

This PR separates available permission flags from per-role permission
flag grants.

Previously, `core.permissionFlag` stored the role assignment directly:
`roleId + flag`. This PR renames that legacy grant table to
`core.rolePermissionFlag`, then recreates `core.permissionFlag` as the
catalog of available permission flags.

## What changed

- Rename the existing `core.permissionFlag` grant table to
`core.rolePermissionFlag`.
- Add the new syncable `core.permissionFlag` catalog entity with key,
label, description, icon, permission type, relevance flags, and
custom/standard metadata.
- Add stable `SystemPermissionFlag` universal identifiers for the
built-in `PermissionFlagType` values.
- Seed the standard permission flags for every workspace under the
Twenty standard application.
- Backfill existing role grants:
  - create missing catalog rows for existing grant keys,
  - add `rolePermissionFlag.permissionFlagId`,
- migrate grants from the old string `flag` column to the new catalog
FK,
- replace the old `(flag, roleId)` uniqueness with `(permissionFlagId,
roleId)`.
- Rewire role permission flag caches, permission checks, role DTO
mapping, and `upsertPermissionFlags` to resolve through the catalog.
- Keep the existing public role permission API shape: product/app
surfaces still talk about `permissionFlags` and return `{ id, roleId,
flag }`.
- Update metadata flat-entity machinery, migration builders, validators,
action handlers, snapshots, generated schemas, docs, and app fixtures
for the new `permissionFlag` / `rolePermissionFlag` split.

## Behavior after this PR

- Existing permission flag grants keep working.
- Existing GraphQL role permission flows keep the same public naming.
- Standard permission flags are represented as catalog rows.
- Permission checks now compare grants through catalog universal
identifiers instead of the legacy `flag` column.
- Workspace deletion cleanup now verifies both `permissionFlag` and
`rolePermissionFlag`.

## What is not in this PR

- Public GraphQL CRUD for custom permission flags.
- App manifest support for declaring new custom permission flags.
- Frontend UI for creating or assigning custom permission flags beyond
the existing role permission flow.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2026-05-18 11:57:47 +00:00
01535a3b3e fix(server): handle network errors in RestApiService catch block (#20644)
## Summary
- Added safe null check for `err.response?.data?.errors` in
`RestApiService.call()` catch block
- When the internal HTTP client fails with a network-level error
(ECONNREFUSED, timeout), `err.response` is `undefined` — accessing
`.data.errors` on it throws a `TypeError` which gets silently swallowed,
returning an empty 500
- Now falls back to throwing the raw error message for network failures
instead of crashing

## Changes
- `packages/twenty-server/src/engine/api/rest/rest-api.service.ts`

Fixes #20136

---------

Co-authored-by: Marie Stoppa <marie@twenty.com>
2026-05-18 09:51:42 +00:00
Shubham SinghandGitHub 45ac3e8218 fix(front): align currency icon vertically with amount text (#20646)
## Summary
- Replaced inline `<span>` wrapping the currency icon with a Linaria
styled component using `display: flex` and `align-items: center`
- The icon was misaligned with the amount text in table views and
settings because the inline span didn't vertically center the SVG icon

## Changes
-
`packages/twenty-front/src/modules/ui/field/display/components/CurrencyDisplay.tsx`

Fixes #20640
2026-05-18 08:48:54 +00:00
cd09690d5d fix(server): correct OpenAPI schema for phones.additionalPhones (#20631)
Fixes #20629

Problem

The OpenAPI schema for PHONES composite fields documented
additionalPhones as string[], but the actual runtime type (defined in
phones.composite-type.ts) is Array<{ number: string, countryCode:
string, callingCode: string }>. This caused generated SDK types and API
docs for create/update payloads to be incorrect.

Root cause

A hardcoded mistake in
convert-object-metadata-to-schema-properties.util.ts — the
FieldMetadataType.PHONES branch set additionalPhones.items to { type:
'string' } instead of an object schema.

Changes


packages/twenty-server/src/engine/utils/convert-object-metadata-to-schema-properties.util.ts
- Changed additionalPhones.items from { type: 'string' } to { type:
'object', properties: { number, countryCode, callingCode } }, matching
AdditionalPhoneMetadata.


packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts
- Updated all three inline snapshot occurrences (for ObjectName,
ObjectNameForResponse, ObjectNameForUpdate) to expect the correct object
shape instead of string.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 08:41:59 +00:00
Charles BochetandGitHub 6b3064e2ba fix(server): add relationTargetFieldMetadataId column early in upgrade sequence (#20664)
## Summary

Cross-version upgrade fails at the 2.3
`DropMessageDirectionFieldCommand` stage:

```
[QueryFailedError] column ViewFilterEntity.relationTargetFieldMetadataId does not exist
  at WorkspaceFlatViewFilterMapCacheService.computeForCache
```

(see
https://github.com/twentyhq/twenty-infra/actions/runs/25929264129/job/76219964380)

Same shape as #20584 (subFieldName), one column over.

### Root cause

1. The 2.3 `DropMessageDirectionFieldCommand` builds a workspace
migration that deletes a `fieldMetadata` (the `direction` field).
2. `WorkspaceMigrationRunnerService.run` walks the metadata cascade
graph and pulls `viewFilter` into the dependency set because
`viewFilter` is the inverse one-to-many of `fieldMetadata`.
3. That maps to cache keys → `flatViewFilterMaps` gets requested →
`WorkspaceFlatViewFilterMapCacheService.computeForCache` runs.
4. `computeForCache` does `viewFilterRepository.find({ where: {
workspaceId }, withDeleted: true })` with no `select`, so TypeORM emits
a SELECT that includes `relationTargetFieldMetadataId` — column only
added by the 2.6 fast instance command `1798000005000`, not yet run at
the 2.3 stage. 💥

### Why v2.5.0 / v2.5.1 passed

They didn't include #20527 (one-hop relation filters, May 14), which
added `relationTargetFieldMetadataId` to `ViewFilterEntity` and the 2.6
instance command. The CI base image (v1.22) seeded the DB, then the
v2.5.0/v2.5.1 container ran upgrade commands against an entity that
didn't yet know about this column.
2026-05-18 10:42:40 +02:00
Charles BochetandGitHub a321e24839 fix(server): scope workspace findOne in incrementMetadataVersion (#20660)
## Summary

Cross-version upgrade fails at the 2.1
`GateExportImportCommandMenuItemsByPermissionFlagCommand` stage:

```
[GateExportImportCommandMenuItemsByPermissionFlagCommand] Found 3 command menu item(s) to update for workspace ...
error: column WorkspaceEntity.isInternalMessagesImportEnabled does not exist
```

(see
https://github.com/twentyhq/twenty-infra/actions/runs/25929264129/job/76219964380)

### Root cause

Same class of bug as #20581 and #20583, one layer deeper in the call
graph.

1. The 2.1 workspace command emits a `commandMenuItem` migration (3
items differ from the current standard expressions).
2. After the migration commits,
`WorkspaceMigrationRunnerService.invalidateCache` walks the
related-for-validation metadata for `commandMenuItem`, which includes
`objectMetadata`. That puts `flatObjectMetadataMaps` in the keys set.
3. `getLegacyCacheInvalidationPromises` sees `flatObjectMetadataMaps` in
the keys and calls
`WorkspaceMetadataVersionService.incrementMetadataVersion(workspaceId)`.
4. `incrementMetadataVersion` did a bare `findOne` on `WorkspaceEntity`
with no `select` → TypeORM emits a SELECT for every column declared on
the entity → hits `isInternalMessagesImportEnabled` (added by #20457),
whose DB column is only created by the 2.5 fast instance command
`1778525104406-add-is-internal-messages-import-enabled`, which has not
run yet at the 2.1 stage. 💥

### Fix

The function only reads `workspace.metadataVersion`, so narrow the
`select` to `['id', 'metadataVersion']`. No behavior change.

```diff
 async incrementMetadataVersion(workspaceId: string): Promise<void> {
   const workspace = await this.workspaceRepository.findOne({
+    select: ['id', 'metadataVersion'],
     where: { id: workspaceId },
     withDeleted: true,
   });
```
2026-05-18 10:36:33 +02:00
nitinandGitHub 3717df34be fix(twenty-front): anchor body text color to theme var (#20622)
Fixes #20607.
also fixes https://github.com/twentyhq/twenty/issues/20627


Front Components rendered via Remote DOM produced black-on-dark text in
dark mode for any unstyled element. `body` already anchored `background`
to a theme var; the matching `color` rule was missing, so unstyled
subtrees fell through to browser default `#000`.

before - 

<img width="850" height="526" alt="CleanShot 2026-05-16 at 16 31 49@2x"
src="https://github.com/user-attachments/assets/ca21359c-d1d1-4367-831e-f694673757e5"
/>

<img width="840" height="1694" alt="CleanShot 2026-05-16 at 16 32 02@2x"
src="https://github.com/user-attachments/assets/ed0891b5-1b97-4499-bb52-9e31c4cabf11"
/>

after - 

<img width="828" height="514" alt="CleanShot 2026-05-16 at 16 30 50@2x"
src="https://github.com/user-attachments/assets/a22d1f1b-a79b-454c-8c05-5c7c00157b2c"
/>

<img width="852" height="1674" alt="CleanShot 2026-05-16 at 16 31 07@2x"
src="https://github.com/user-attachments/assets/9b1dc19e-ccc5-472b-9184-59fa9b8832f8"
/>
2026-05-18 10:29:22 +02:00
Shubham SinghandGitHub 140dceebd1 fix(front): use theme-aware color for side panel title (#20645)
## Summary
- Added `color: ${themeCssVariables.font.color.primary}` to
`StyledPageInfoTitleContainer` in `SidePanelPageInfoLayout.tsx`
- The "Update records" title had no explicit color, so it didn't adapt
to dark mode and was nearly invisible against the dark background
- Now correctly uses the theme-aware primary font color

## Changes
-
`packages/twenty-front/src/modules/side-panel/components/SidePanelPageInfoLayout.tsx`

Fixes #20627
2026-05-18 10:25:34 +02:00
4d2ceaf70a i18n - translations (#20661)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-18 10:20:30 +02:00
Félix MalfaitandGitHub 6b49a14b9f feat(auth): set 50-character maximum length on passwords (#20655)
## Summary
- Cap password length at 50 characters in the shared regex used by
sign-up, password reset, and password change (both `twenty-front` and
`twenty-server`).
- Update the user-facing validation message on sign-up and password
reset to mention both the 8 min and 50 max bounds.
- Extend the `PASSWORD_REGEX` unit test to cover the new upper bound.

The cap also prevents unbounded inputs from reaching bcrypt, which
silently truncates passwords above 72 bytes and can mask user-visible
bugs.

## Test plan
- [x] `npx jest src/modules/auth/utils/__tests__/passwordRegex.test.ts`
passes (8-char min and 50-char max).
- [ ] Sign up with a 51-character password — form rejects with "Password
must be between 8 and 50 characters".
- [ ] Sign up with an 8–50 character password — succeeds.
- [ ] Password reset rejects a 51-character password with the same
message.
- [ ] Existing users with longer passwords (if any pre-exist) can still
sign in (the regex only gates write paths: sign-up, change, reset).
2026-05-18 10:12:19 +02:00
338 changed files with 11210 additions and 2381 deletions
@@ -244,7 +244,7 @@ type FieldPermission {
canUpdateFieldValue: Boolean
}
type PermissionFlag {
type RolePermissionFlag {
id: UUID!
roleId: UUID!
flag: PermissionFlagType!
@@ -276,7 +276,7 @@ type Role {
canUpdateAllObjectRecords: Boolean!
canSoftDeleteAllObjectRecords: Boolean!
canDestroyAllObjectRecords: Boolean!
permissionFlags: [PermissionFlag!]
permissionFlags: [RolePermissionFlag!]
objectPermissions: [ObjectPermission!]
fieldPermissions: [FieldPermission!]
rowLevelPermissionPredicates: [RowLevelPermissionPredicate!]
@@ -2884,6 +2884,7 @@ enum AllMetadataName {
pageLayoutTab
commandMenuItem
navigationMenuItem
rolePermissionFlag
permissionFlag
objectPermission
fieldPermission
@@ -3237,7 +3238,7 @@ type Mutation {
updateOneRole(updateRoleInput: UpdateRoleInput!): Role!
deleteOneRole(roleId: UUID!): String!
upsertObjectPermissions(upsertObjectPermissionsInput: UpsertObjectPermissionsInput!): [ObjectPermission!]!
upsertPermissionFlags(upsertPermissionFlagsInput: UpsertPermissionFlagsInput!): [PermissionFlag!]!
upsertPermissionFlags(upsertPermissionFlagsInput: UpsertPermissionFlagsInput!): [RolePermissionFlag!]!
upsertFieldPermissions(upsertFieldPermissionsInput: UpsertFieldPermissionsInput!): [FieldPermission!]!
upsertRowLevelPermissionPredicates(input: UpsertRowLevelPermissionPredicatesInput!): UpsertRowLevelPermissionPredicatesResult!
assignRoleToAgent(agentId: UUID!, roleId: UUID!): Boolean!
@@ -3262,7 +3263,7 @@ type Mutation {
updateWebhook(input: UpdateWebhookInput!): Webhook!
deleteWebhook(id: UUID!): Webhook!
createChatThread: AgentChatThread!
sendChatMessage(threadId: UUID!, text: String!, messageId: UUID!, browsingContext: JSON, modelId: String, fileIds: [UUID!]): SendChatMessageResult!
sendChatMessage(threadId: UUID!, text: String!, messageId: UUID!, browsingContext: JSON, modelId: String, fileAttachments: [FileAttachmentInput!]): SendChatMessageResult!
stopAgentChatStream(threadId: UUID!): Boolean!
renameChatThread(id: UUID!, title: String!): AgentChatThread!
archiveChatThread(id: UUID!): AgentChatThread!
@@ -4227,6 +4228,11 @@ input UpdateWebhookInputUpdates {
secret: String
}
input FileAttachmentInput {
id: UUID!
filename: String!
}
input CreateSkillInput {
id: UUID
name: String!
@@ -190,11 +190,11 @@ export interface FieldPermission {
__typename: 'FieldPermission'
}
export interface PermissionFlag {
export interface RolePermissionFlag {
id: Scalars['UUID']
roleId: Scalars['UUID']
flag: PermissionFlagType
__typename: 'PermissionFlag'
__typename: 'RolePermissionFlag'
}
export interface ApiKeyForRole {
@@ -224,7 +224,7 @@ export interface Role {
canUpdateAllObjectRecords: Scalars['Boolean']
canSoftDeleteAllObjectRecords: Scalars['Boolean']
canDestroyAllObjectRecords: Scalars['Boolean']
permissionFlags?: PermissionFlag[]
permissionFlags?: RolePermissionFlag[]
objectPermissions?: ObjectPermission[]
fieldPermissions?: FieldPermission[]
rowLevelPermissionPredicates?: RowLevelPermissionPredicate[]
@@ -2516,7 +2516,7 @@ export interface CollectionHash {
__typename: 'CollectionHash'
}
export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'permissionFlag' | 'objectPermission' | 'fieldPermission' | 'frontComponent' | 'webhook' | 'applicationVariable' | 'connectionProvider'
export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'rolePermissionFlag' | 'permissionFlag' | 'objectPermission' | 'fieldPermission' | 'frontComponent' | 'webhook' | 'applicationVariable' | 'connectionProvider'
export interface MinimalObjectMetadata {
id: Scalars['UUID']
@@ -2772,7 +2772,7 @@ export interface Mutation {
updateOneRole: Role
deleteOneRole: Scalars['String']
upsertObjectPermissions: ObjectPermission[]
upsertPermissionFlags: PermissionFlag[]
upsertPermissionFlags: RolePermissionFlag[]
upsertFieldPermissions: FieldPermission[]
upsertRowLevelPermissionPredicates: UpsertRowLevelPermissionPredicatesResult
assignRoleToAgent: Scalars['Boolean']
@@ -3072,7 +3072,7 @@ export interface FieldPermissionGenqlSelection{
__scalar?: boolean | number
}
export interface PermissionFlagGenqlSelection{
export interface RolePermissionFlagGenqlSelection{
id?: boolean | number
roleId?: boolean | number
flag?: boolean | number
@@ -3108,7 +3108,7 @@ export interface RoleGenqlSelection{
canUpdateAllObjectRecords?: boolean | number
canSoftDeleteAllObjectRecords?: boolean | number
canDestroyAllObjectRecords?: boolean | number
permissionFlags?: PermissionFlagGenqlSelection
permissionFlags?: RolePermissionFlagGenqlSelection
objectPermissions?: ObjectPermissionGenqlSelection
fieldPermissions?: FieldPermissionGenqlSelection
rowLevelPermissionPredicates?: RowLevelPermissionPredicateGenqlSelection
@@ -5847,7 +5847,7 @@ export interface MutationGenqlSelection{
updateOneRole?: (RoleGenqlSelection & { __args: {updateRoleInput: UpdateRoleInput} })
deleteOneRole?: { __args: {roleId: Scalars['UUID']} }
upsertObjectPermissions?: (ObjectPermissionGenqlSelection & { __args: {upsertObjectPermissionsInput: UpsertObjectPermissionsInput} })
upsertPermissionFlags?: (PermissionFlagGenqlSelection & { __args: {upsertPermissionFlagsInput: UpsertPermissionFlagsInput} })
upsertPermissionFlags?: (RolePermissionFlagGenqlSelection & { __args: {upsertPermissionFlagsInput: UpsertPermissionFlagsInput} })
upsertFieldPermissions?: (FieldPermissionGenqlSelection & { __args: {upsertFieldPermissionsInput: UpsertFieldPermissionsInput} })
upsertRowLevelPermissionPredicates?: (UpsertRowLevelPermissionPredicatesResultGenqlSelection & { __args: {input: UpsertRowLevelPermissionPredicatesInput} })
assignRoleToAgent?: { __args: {agentId: Scalars['UUID'], roleId: Scalars['UUID']} }
@@ -5872,7 +5872,7 @@ export interface MutationGenqlSelection{
updateWebhook?: (WebhookGenqlSelection & { __args: {input: UpdateWebhookInput} })
deleteWebhook?: (WebhookGenqlSelection & { __args: {id: Scalars['UUID']} })
createChatThread?: AgentChatThreadGenqlSelection
sendChatMessage?: (SendChatMessageResultGenqlSelection & { __args: {threadId: Scalars['UUID'], text: Scalars['String'], messageId: Scalars['UUID'], browsingContext?: (Scalars['JSON'] | null), modelId?: (Scalars['String'] | null), fileIds?: (Scalars['UUID'][] | null)} })
sendChatMessage?: (SendChatMessageResultGenqlSelection & { __args: {threadId: Scalars['UUID'], text: Scalars['String'], messageId: Scalars['UUID'], browsingContext?: (Scalars['JSON'] | null), modelId?: (Scalars['String'] | null), fileAttachments?: (FileAttachmentInput[] | null)} })
stopAgentChatStream?: { __args: {threadId: Scalars['UUID']} }
renameChatThread?: (AgentChatThreadGenqlSelection & { __args: {id: Scalars['UUID'], title: Scalars['String']} })
archiveChatThread?: (AgentChatThreadGenqlSelection & { __args: {id: Scalars['UUID']} })
@@ -6259,6 +6259,8 @@ update: UpdateWebhookInputUpdates}
export interface UpdateWebhookInputUpdates {targetUrl?: (Scalars['String'] | null),operations?: (Scalars['String'][] | null),description?: (Scalars['String'] | null),secret?: (Scalars['String'] | null)}
export interface FileAttachmentInput {id: Scalars['UUID'],filename: Scalars['String']}
export interface CreateSkillInput {id?: (Scalars['UUID'] | null),name: Scalars['String'],label: Scalars['String'],icon?: (Scalars['String'] | null),description?: (Scalars['String'] | null),content: Scalars['String']}
export interface UpdateSkillInput {id: Scalars['UUID'],name?: (Scalars['String'] | null),label?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),description?: (Scalars['String'] | null),content?: (Scalars['String'] | null),isActive?: (Scalars['Boolean'] | null)}
@@ -6426,10 +6428,10 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const PermissionFlag_possibleTypes: string[] = ['PermissionFlag']
export const isPermissionFlag = (obj?: { __typename?: any } | null): obj is PermissionFlag => {
if (!obj?.__typename) throw new Error('__typename is missing in "isPermissionFlag"')
return PermissionFlag_possibleTypes.includes(obj.__typename)
const RolePermissionFlag_possibleTypes: string[] = ['RolePermissionFlag']
export const isRolePermissionFlag = (obj?: { __typename?: any } | null): obj is RolePermissionFlag => {
if (!obj?.__typename) throw new Error('__typename is missing in "isRolePermissionFlag"')
return RolePermissionFlag_possibleTypes.includes(obj.__typename)
}
@@ -8899,6 +8901,7 @@ export const enumAllMetadataName = {
pageLayoutTab: 'pageLayoutTab' as const,
commandMenuItem: 'commandMenuItem' as const,
navigationMenuItem: 'navigationMenuItem' as const,
rolePermissionFlag: 'rolePermissionFlag' as const,
permissionFlag: 'permissionFlag' as const,
objectPermission: 'objectPermission' as const,
fieldPermission: 'fieldPermission' as const,
@@ -78,8 +78,8 @@ export default {
335,
342,
378,
454,
466
455,
467
],
"types": {
"BillingProductDTO": {
@@ -500,7 +500,7 @@ export default {
1
]
},
"PermissionFlag": {
"RolePermissionFlag": {
"id": [
3
],
@@ -7876,9 +7876,9 @@ export default {
"modelId": [
1
],
"fileIds": [
3,
"[UUID!]"
"fileAttachments": [
440,
"[FileAttachmentInput!]"
]
}
],
@@ -7944,7 +7944,7 @@ export default {
290,
{
"input": [
440,
441,
"CreateSkillInput!"
]
}
@@ -7953,7 +7953,7 @@ export default {
290,
{
"input": [
441,
442,
"UpdateSkillInput!"
]
}
@@ -8011,7 +8011,7 @@ export default {
238,
{
"input": [
442,
443,
"GetAuthorizationUrlForSSOInput!"
]
}
@@ -8265,7 +8265,7 @@ export default {
196,
{
"input": [
443,
444,
"CreateApplicationRegistrationInput!"
]
}
@@ -8274,7 +8274,7 @@ export default {
7,
{
"input": [
444,
445,
"UpdateApplicationRegistrationInput!"
]
}
@@ -8301,7 +8301,7 @@ export default {
5,
{
"input": [
446,
447,
"CreateApplicationRegistrationVariableInput!"
]
}
@@ -8310,7 +8310,7 @@ export default {
5,
{
"input": [
447,
448,
"UpdateApplicationRegistrationVariableInput!"
]
}
@@ -8399,7 +8399,7 @@ export default {
6,
{
"input": [
449,
450,
"UpdateWorkspaceMemberSettingsInput!"
]
}
@@ -8433,7 +8433,7 @@ export default {
75,
{
"data": [
450,
451,
"ActivateWorkspaceInput!"
]
}
@@ -8442,7 +8442,7 @@ export default {
75,
{
"data": [
451,
452,
"UpdateWorkspaceInput!"
]
}
@@ -8469,7 +8469,7 @@ export default {
6,
{
"workspaceMigration": [
452,
453,
"WorkspaceMigrationInput!"
]
}
@@ -8487,7 +8487,7 @@ export default {
220,
{
"input": [
455,
456,
"SetupOIDCSsoInput!"
]
}
@@ -8496,7 +8496,7 @@ export default {
220,
{
"input": [
456,
457,
"SetupSAMLSsoInput!"
]
}
@@ -8505,7 +8505,7 @@ export default {
216,
{
"input": [
457,
458,
"DeleteSsoInput!"
]
}
@@ -8514,7 +8514,7 @@ export default {
217,
{
"input": [
458,
459,
"EditSsoInput!"
]
}
@@ -8545,7 +8545,7 @@ export default {
286,
{
"input": [
459,
460,
"SendEmailInput!"
]
}
@@ -8571,7 +8571,7 @@ export default {
"String!"
],
"connectionParameters": [
461,
462,
"EmailAccountConnectionParameters!"
],
"id": [
@@ -8583,7 +8583,7 @@ export default {
168,
{
"input": [
463,
464,
"UpdateLabPublicFeatureFlagInput!"
]
}
@@ -8665,7 +8665,7 @@ export default {
77,
{
"input": [
464,
465,
"CreateOneAppTokenInput!"
]
}
@@ -8728,7 +8728,7 @@ export default {
"String!"
],
"fileFolder": [
466,
467,
"FileFolder!"
],
"filePath": [
@@ -10746,6 +10746,17 @@ export default {
1
]
},
"FileAttachmentInput": {
"id": [
3
],
"filename": [
1
],
"__typename": [
1
]
},
"CreateSkillInput": {
"id": [
3
@@ -10828,7 +10839,7 @@ export default {
1
],
"update": [
445
446
],
"__typename": [
1
@@ -10876,7 +10887,7 @@ export default {
1
],
"update": [
448
449
],
"__typename": [
1
@@ -10994,7 +11005,7 @@ export default {
},
"WorkspaceMigrationInput": {
"actions": [
453
454
],
"__typename": [
1
@@ -11002,7 +11013,7 @@ export default {
},
"WorkspaceMigrationDeleteActionInput": {
"type": [
454
455
],
"metadataName": [
318
@@ -11097,7 +11108,7 @@ export default {
1
],
"files": [
460
461
],
"__typename": [
1
@@ -11116,13 +11127,13 @@ export default {
},
"EmailAccountConnectionParameters": {
"IMAP": [
462
463
],
"SMTP": [
462
463
],
"CALDAV": [
462
463
],
"__typename": [
1
@@ -11161,7 +11172,7 @@ export default {
},
"CreateOneAppTokenInput": {
"appToken": [
465
466
],
"__typename": [
1
@@ -11190,7 +11201,7 @@ export default {
230,
{
"input": [
468,
469,
"LogicFunctionLogsInput!"
]
}
@@ -1,7 +1,7 @@
---
title: Roles & Permissions
description: Declare what objects and fields your app's logic functions and front components can read and write.
icon: "shield-halved"
icon: 'shield-halved'
---
A **role** is a permission set: which objects an app can read or write, which fields it can see, and which platform-level capabilities it can use. Every app's logic functions and front components inherit the permissions of the role marked with `defineApplicationRole()` (see [The default function role](#the-default-function-role) below).
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -80,6 +81,7 @@ export default defineApplicationRole({
`defineApplicationRole()` is a thin wrapper around `defineRole()` that flags **the** role used as your application's default at install time. Validation is identical to `defineRole`, but the build pipeline auto-wires its `universalIdentifier` into the application manifest's `defaultRoleUniversalIdentifier` — so you do not need to reference it from [`defineApplication`](/developers/extend/apps/config/application) yourself.
Notes:
- Exactly **one** `defineApplicationRole(...)` is allowed per app — the manifest build will fail if it finds more than one.
- Use `defineRole()` (not `defineApplicationRole()`) for any **additional** roles your app ships.
- Setting `defaultRoleUniversalIdentifier` explicitly on `defineApplication()` is still supported for backward compatibility, but is deprecated in favor of `defineApplicationRole()`.
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
@@ -40,7 +40,8 @@ export default defineRole({
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
fieldUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
.universalIdentifier,
canReadFieldValue: false,
canUpdateFieldValue: false,
},
File diff suppressed because one or more lines are too long
+1
View File
@@ -4,6 +4,7 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: var(--t-background-tertiary);
color: var(--t-font-color-primary);
}
html {
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Terug na {linkText}"
msgid "Back to content"
msgstr "Terug na inhoud"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Terug na Instellings"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Wagwoord is gestel"
msgid "Password has been updated"
msgstr "Wagwoord is opgedateer"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Wagwoord moet minstens 8 karakters wees"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rolnaam"
msgid "Role name cannot be empty"
msgstr "Rolnaam kan nie leeg wees nie"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "العودة إلى {linkText}"
msgid "Back to content"
msgstr "العودة إلى المحتوى"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "العودة إلى الإعدادات"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "تم تعيين كلمة المرور"
msgid "Password has been updated"
msgstr "تم تحديث كلمة السر"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "يجب أن تكون كلمة المرور 8 أحرف على الأقل"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "اسم الدور"
msgid "Role name cannot be empty"
msgstr "لا يمكن أن يكون اسم الدور فارغًا"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Torna a {linkText}"
msgid "Back to content"
msgstr "Tornar al contingut"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Torna a Configuració"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "La contrasenya s'ha establert"
msgid "Password has been updated"
msgstr "La contrasenya s'ha actualitzat"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "La contrasenya ha de tenir almenys 8 caràcters"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nom del rol"
msgid "Role name cannot be empty"
msgstr "El nom del rol no pot estar buit"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Zpět na {linkText}"
msgid "Back to content"
msgstr "Zpět k obsahu"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Zpět do nastavení"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Heslo bylo nastaveno"
msgid "Password has been updated"
msgstr "Heslo bylo aktualizováno"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Heslo musí mít alespoň 8 znaků"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Název role"
msgid "Role name cannot be empty"
msgstr "Název role nesmí být prázdný"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Tilbage til {linkText}"
msgid "Back to content"
msgstr "Tilbage til indhold"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Tilbage til Indstillinger"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Adgangskoden er blevet sat"
msgid "Password has been updated"
msgstr "Password er blevet opdateret"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Adgangskode skal være min. 8 tegn"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rollenavn"
msgid "Role name cannot be empty"
msgstr "Rollens navn kan ikke være tomt"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Zurück zu {linkText}"
msgid "Back to content"
msgstr "Zurück zum Inhalt"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Zurück zu den Einstellungen"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Das Passwort wurde aktualisiert"
msgid "Password has been updated"
msgstr "Das Passwort wurde aktualisiert"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Passwort muss mind. 8 Zeichen lang sein"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rollenname"
msgid "Role name cannot be empty"
msgstr "Rollenname darf nicht leer sein"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Πίσω στο {linkText}"
msgid "Back to content"
msgstr "Επιστροφή στο περιεχόμενο"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Πίσω στις Ρυθμίσεις"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Ο κωδικός πρόσβασης έχει ρυθμιστεί"
msgid "Password has been updated"
msgstr "Ο κωδικός έχει ενημερωθεί"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Ο κωδικός πρόσβασης πρέπει να είναι τουλάχιστον 8 χαρακτήρες"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Όνομα ρόλου"
msgid "Role name cannot be empty"
msgstr "Το όνομα του ρόλου δεν μπορεί να είναι κενό"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2647,11 +2647,6 @@ msgstr "Back to {linkText}"
msgid "Back to content"
msgstr "Back to content"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Back to Settings"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11819,11 +11814,11 @@ msgstr "Password has been set"
msgid "Password has been updated"
msgstr "Password has been updated"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Password must be min. 8 characters"
msgid "Password must be between 8 and 50 characters"
msgstr "Password must be between 8 and 50 characters"
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13196,6 +13191,11 @@ msgstr "Role name"
msgid "Role name cannot be empty"
msgstr "Role name cannot be empty"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr "role permission flag"
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Volver a {linkText}"
msgid "Back to content"
msgstr "Volver al contenido"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Volver a Configuración"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "La contraseña ha sido establecida"
msgid "Password has been updated"
msgstr "La contraseña ha sido actualizada"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "La contraseña debe tener al menos 8 caracteres"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nombre del rol"
msgid "Role name cannot be empty"
msgstr "El nombre del rol no puede estar vacío"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Takaisin kohteeseen {linkText}"
msgid "Back to content"
msgstr "Takaisin sisältöön"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Takaisin asetuksiin"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Salasana on asetettu"
msgid "Password has been updated"
msgstr "Salasana on päivitetty"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Salasanassa on oltava vähintään 8 merkkiä"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Roolin nimi"
msgid "Role name cannot be empty"
msgstr "Roolinimi ei saa olla tyhjä"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Retour à {linkText}"
msgid "Back to content"
msgstr "Retour au contenu"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Retour aux paramètres"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Le mot de passe a été défini"
msgid "Password has been updated"
msgstr "Le mot de passe a été mis à jour"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Le mot de passe doit comporter au minimum 8 caractères"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nom du rôle"
msgid "Role name cannot be empty"
msgstr "Le nom du rôle ne peut pas être vide"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "חזרה אל {linkText}"
msgid "Back to content"
msgstr "חזרה לתוכן"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "חזרה להגדרות"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "הסיסמה עודכנה"
msgid "Password has been updated"
msgstr "הסיסמה עודכנה"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "הסיסמה חייבת להיות באורך מינימום 8 תווים"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "שם התפקיד"
msgid "Role name cannot be empty"
msgstr "שם תפקיד לא יכול להיות ריק"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Vissza ide: {linkText}"
msgid "Back to content"
msgstr "Vissza a tartalomhoz"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Vissza a beállításokhoz"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "A jelszót beállították"
msgid "Password has been updated"
msgstr "A jelszót frissítették"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "A jelszónak legalább 8 karakter hosszúnak kell lennie"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Szerepkör neve"
msgid "Role name cannot be empty"
msgstr "A szerep neve nem lehet üres"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Torna a {linkText}"
msgid "Back to content"
msgstr "Torna al contenuto"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Torna alle Impostazioni"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "La password è stata impostata"
msgid "Password has been updated"
msgstr "La password è stata aggiornata"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "La password deve essere di almeno 8 caratteri"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nome del ruolo"
msgid "Role name cannot be empty"
msgstr "Il nome del ruolo non può essere vuoto"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "{linkText} に戻る"
msgid "Back to content"
msgstr "コンテンツに戻る"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "設定に戻る"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "パスワードが設定されました"
msgid "Password has been updated"
msgstr "パスワードが更新されました"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "パスワードは8文字以上である必要があります"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "役割名"
msgid "Role name cannot be empty"
msgstr "役割名を空にすることはできません"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "{linkText}(으)로 돌아가기"
msgid "Back to content"
msgstr "콘텐츠로 돌아가기"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "설정으로 돌아가기"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "비밀번호가 설정되었습니다"
msgid "Password has been updated"
msgstr "비밀번호가 업데이트되었습니다"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "비밀번호는 최소 8자여야 합니다"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "역할 이름"
msgid "Role name cannot be empty"
msgstr "역할 이름은 비워 둘 수 없습니다"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Terug naar {linkText}"
msgid "Back to content"
msgstr "Terug naar inhoud"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Terug naar Instellingen"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Wachtwoord is ingesteld"
msgid "Password has been updated"
msgstr "Wachtwoord is geüpdated"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Wachtwoord moet min. 8 tekens bevatten"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rolnaam"
msgid "Role name cannot be empty"
msgstr "Rolnaam mag niet leeg zijn"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Tilbake til {linkText}"
msgid "Back to content"
msgstr "Tilbake til innhold"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Tilbake til Innstillinger"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Passordet har blitt satt"
msgid "Password has been updated"
msgstr "Passordet har blitt oppdatert"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Passord må være minst 8 tegn"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rollenavn"
msgid "Role name cannot be empty"
msgstr "Rollens navn kan ikke være tomt"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Powrót do {linkText}"
msgid "Back to content"
msgstr "Powrót do treści"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Powrót do ustawień"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Hasło zostało ustawione"
msgid "Password has been updated"
msgstr "Hasło zostało zaktualizowane"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Hasło musi mieć min. 8 znaków"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nazwa roli"
msgid "Role name cannot be empty"
msgstr "Nazwa roli nie może być pusta"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
@@ -2647,11 +2647,6 @@ msgstr ""
msgid "Back to content"
msgstr ""
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr ""
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11796,10 +11791,10 @@ msgstr ""
msgid "Password has been updated"
msgstr ""
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
@@ -13173,6 +13168,11 @@ msgstr ""
msgid "Role name cannot be empty"
msgstr ""
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Voltar para {linkText}"
msgid "Back to content"
msgstr "Voltar ao conteúdo"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Voltar para Configurações"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "A senha foi definida"
msgid "Password has been updated"
msgstr "A senha foi atualizada"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "A senha deve ter no mínimo 8 caracteres"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nome do cargo"
msgid "Role name cannot be empty"
msgstr "O nome da função não pode estar vazio"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Voltar a {linkText}"
msgid "Back to content"
msgstr "Voltar ao conteúdo"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Voltar às Definições"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "A palavra-passe foi definida"
msgid "Password has been updated"
msgstr "A palavra-passe foi atualizada"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "A palavra-passe deve ter no mínimo 8 caracteres"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Nome do papel"
msgid "Role name cannot be empty"
msgstr "O nome do papel não pode estar vazio"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Înapoi la {linkText}"
msgid "Back to content"
msgstr "Înapoi la conținut"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Înapoi la Setări"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Parola a fost setată"
msgid "Password has been updated"
msgstr "Parola a fost actualizată"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Parola trebuie să aibă minimum 8 caractere"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Numele rolului"
msgid "Role name cannot be empty"
msgstr "Numele rolului nu poate fi gol"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
Binary file not shown.
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Назад на {linkText}"
msgid "Back to content"
msgstr "Назад на садржај"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Назад на Подешавања"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Лозинка је постављена"
msgid "Password has been updated"
msgstr "Лозинка је ажурирана"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Лозинка мора имати најмање 8 знакова"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Назив улоге"
msgid "Role name cannot be empty"
msgstr "Назив улоге не може бити празан"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Tillbaka till {linkText}"
msgid "Back to content"
msgstr "Tillbaka till innehåll"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Tillbaka till inställningar"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11803,11 +11798,11 @@ msgstr "Lösenordet har ställts in"
msgid "Password has been updated"
msgstr "Lösenordet har uppdaterats"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Lösenord måste vara minst 8 tecken"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13180,6 +13175,11 @@ msgstr "Rollnamn"
msgid "Role name cannot be empty"
msgstr "Rollnamn får inte vara tomt"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "{linkText}'e geri dön"
msgid "Back to content"
msgstr "İçeriğe geri dön"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Ayarlar'a geri dön"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Parola ayarlandı"
msgid "Password has been updated"
msgstr "Parola güncellendi"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Parola en az 8 karakter olmalıdır"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Rol adı"
msgid "Role name cannot be empty"
msgstr "Rol adı boş olamaz"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Назад до {linkText}"
msgid "Back to content"
msgstr "Повернутися до вмісту"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Назад до налаштувань"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Пароль було встановлено"
msgid "Password has been updated"
msgstr "Пароль було оновлено"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Пароль має містити щонайменше 8 символів"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Назва ролі"
msgid "Role name cannot be empty"
msgstr "Назва ролі не може бути порожньою"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "Quay lại {linkText}"
msgid "Back to content"
msgstr "Quay lại nội dung"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "Quay lại Cài đặt"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "Mật khẩu đã được thiết lập"
msgid "Password has been updated"
msgstr "Mật khẩu đã được cập nhật"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "Mật khẩu phải có tối thiểu 8 ký tự"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "Tên vai trò"
msgid "Role name cannot be empty"
msgstr "Tên vai trò không thể để trống"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "返回 {linkText}"
msgid "Back to content"
msgstr "返回内容"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "返回设置"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "密码已更新"
msgid "Password has been updated"
msgstr "密码已更新"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "密码长度至少为 8 个字符"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "角色名称"
msgid "Role name cannot be empty"
msgstr "角色名称不能为空"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
+8 -8
View File
@@ -2652,11 +2652,6 @@ msgstr "返回 {linkText}"
msgid "Back to content"
msgstr "返回內容"
#. js-lingui-id: OvBnOM
#: src/modules/ui/navigation/bread-crumb/components/MobileBreadcrumb.tsx
msgid "Back to Settings"
msgstr "返回設定"
#. js-lingui-id: GtJbUa
#: src/modules/error-handler/components/AppRootErrorFallback.tsx
msgid "Background"
@@ -11801,11 +11796,11 @@ msgstr "密碼已設定"
msgid "Password has been updated"
msgstr "密碼已更新"
#. js-lingui-id: 1oqxe6
#. js-lingui-id: BfLK2u
#: src/pages/auth/PasswordReset.tsx
#: src/modules/auth/sign-in-up/hooks/useSignInUpForm.ts
msgid "Password must be min. 8 characters"
msgstr "密碼至少需 8 個字元"
msgid "Password must be between 8 and 50 characters"
msgstr ""
#. js-lingui-id: mi6Rel
#: src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts
@@ -13178,6 +13173,11 @@ msgstr "角色名稱"
msgid "Role name cannot be empty"
msgstr "角色名稱不能為空"
#. js-lingui-id: VMX1Oy
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role permission flag"
msgstr ""
#. js-lingui-id: jLNGne
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "role target"
@@ -7,7 +7,7 @@ export const SEND_CHAT_MESSAGE = gql`
$messageId: UUID!
$browsingContext: JSON
$modelId: String
$fileIds: [UUID!]
$fileAttachments: [FileAttachmentInput!]
) {
sendChatMessage(
threadId: $threadId
@@ -15,7 +15,7 @@ export const SEND_CHAT_MESSAGE = gql`
messageId: $messageId
browsingContext: $browsingContext
modelId: $modelId
fileIds: $fileIds
fileAttachments: $fileAttachments
) {
messageId
queued
@@ -30,7 +30,6 @@ import { useListenToBrowserEvent } from '@/browser-event/hooks/useListenToBrowse
import { dispatchBrowserEvent } from '@/browser-event/utils/dispatchBrowserEvent';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
export const useAgentChat = (
@@ -44,11 +43,9 @@ export const useAgentChat = (
const setCurrentAiChatThread = useSetAtomState(currentAiChatThreadState);
const store = useStore();
const agentChatSelectedFiles = useAtomStateValue(agentChatSelectedFilesState);
const [, setPendingThreadIdAfterFirstSend] = useState<string | null>(null);
const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useAtomState(
const setAgentChatUploadedFiles = useSetAtomState(
agentChatUploadedFilesState,
);
@@ -74,12 +71,14 @@ export const useAgentChat = (
return;
}
const isLoading = agentChatSelectedFiles.length > 0;
const agentChatSelectedFiles = store.get(agentChatSelectedFilesState.atom);
if (isLoading) {
if (agentChatSelectedFiles.length > 0) {
return;
}
const agentChatUploadedFiles = store.get(agentChatUploadedFilesState.atom);
const threadId = await ensureThreadIdForSend();
if (!isDefined(threadId)) {
@@ -131,7 +130,11 @@ export const useAgentChat = (
store.set(messagesAtom, [...currentMessages, optimisticUserMessage]);
store.set(errorAtom, null);
const fileIds = agentChatUploadedFiles.map((file) => file.fileId);
const fileAttachments = agentChatUploadedFiles.map((file) => ({
id: file.fileId,
filename: file.filename,
}));
const uploadedFilesSnapshot = agentChatUploadedFiles;
setAgentChatUploadedFiles([]);
@@ -150,7 +153,8 @@ export const useAgentChat = (
messageId,
browsingContext: browsingContext ?? null,
modelId: modelIdForRequest ?? undefined,
fileIds: fileIds.length > 0 ? fileIds : undefined,
fileAttachments:
fileAttachments.length > 0 ? fileAttachments : undefined,
},
});
@@ -186,6 +190,7 @@ export const useAgentChat = (
? { [AGENT_CHAT_NEW_THREAD_DRAFT_KEY]: '' }
: {}),
}));
setAgentChatUploadedFiles(uploadedFilesSnapshot);
const latestMessages = store.get(messagesAtom);
@@ -214,11 +219,9 @@ export const useAgentChat = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
store,
agentChatSelectedFiles,
ensureThreadIdForSend,
setAgentChatInput,
getBrowsingContext,
agentChatUploadedFiles,
setAgentChatUploadedFiles,
setAgentChatDraftsByThreadId,
modelIdForRequest,
@@ -26,7 +26,10 @@ const makeValidationSchema = (signInUpStep: SignInUpStep) =>
signInUpStep === SignInUpStep.Password
? z
.string()
.regex(PASSWORD_REGEX, t`Password must be min. 8 characters`)
.regex(
PASSWORD_REGEX,
t`Password must be between 8 and 50 characters`,
)
: z.string().optional(),
captchaToken: z.string().default(''),
})
@@ -8,4 +8,12 @@ describe('PASSWORD_REGEX', () => {
expect(PASSWORD_REGEX.test(validPassword)).toBe(true);
expect(PASSWORD_REGEX.test(invalidPassword)).toBe(false);
});
it('should match passwords with at most 50 characters', () => {
const validPassword = 'a'.repeat(50);
const invalidPassword = 'a'.repeat(51);
expect(PASSWORD_REGEX.test(validPassword)).toBe(true);
expect(PASSWORD_REGEX.test(invalidPassword)).toBe(false);
});
});
@@ -1 +1 @@
export const PASSWORD_REGEX = /^.{8,}$/;
export const PASSWORD_REGEX = /^.{8,50}$/;
@@ -30,6 +30,7 @@ export const useMetadataErrorHandler = () => {
viewFilter: t`view filter`,
index: t`index`,
logicFunction: t`logic function`,
rolePermissionFlag: t`role permission flag`,
permissionFlag: t`permission flag`,
objectPermission: t`object permission`,
fieldPermission: t`field permission`,
@@ -120,7 +120,7 @@ const StyledNewChatButton = styled.div`
justify-content: center;
min-width: 0;
overflow: hidden;
padding-inline: ${themeCssVariables.spacing[1]};
padding-inline: ${themeCssVariables.spacing[2]};
transition:
background calc(${themeCssVariables.animation.duration.fast} * 1s) ease,
color calc(${themeCssVariables.animation.duration.fast} * 1s) ease;
@@ -10,6 +10,7 @@ import { useOpenRecordsSearchPageInSidePanel } from '@/side-panel/hooks/useOpenR
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
import { isSidePanelOpenedState } from '@/side-panel/states/isSidePanelOpenedState';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -29,6 +30,7 @@ export const MobileNavigationBar = () => {
const navigate = useNavigate();
const { defaultHomePagePath } = useDefaultHomePagePath();
const isSidePanelOpened = useAtomStateValue(isSidePanelOpenedState);
const navigationMemorizedUrl = useAtomStateValue(navigationMemorizedUrlState);
const { closeSidePanelMenu } = useSidePanelMenu();
const { openRecordsSearchPage } = useOpenRecordsSearchPageInSidePanel();
const isSettingsPage = useIsSettingsPage();
@@ -70,7 +72,11 @@ export const MobileNavigationBar = () => {
setCurrentMobileNavigationDrawer('main');
if (isSettingsPage) {
navigate(defaultHomePagePath);
navigate(
navigationMemorizedUrl !== '/'
? navigationMemorizedUrl
: defaultHomePagePath,
);
}
},
},
@@ -9,7 +9,7 @@ export const useIsSettingsDrawer = () => {
const currentMobileNavigationDrawer = useAtomStateValue(
currentMobileNavigationDrawerState,
);
return isMobile
? currentMobileNavigationDrawer === 'settings'
: isSettingsPage;
return (
isSettingsPage || (isMobile && currentMobileNavigationDrawer === 'settings')
);
};
@@ -1,11 +1,15 @@
import { useIsSettingsDrawer } from '@/navigation/hooks/useIsSettingsDrawer';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
export const useNavigationDrawerExpanded = () => {
const isMobile = useIsMobile();
const isSettingsDrawer = useIsSettingsDrawer();
const isNavigationDrawerExpanded = useAtomStateValue(
isNavigationDrawerExpandedState,
);
return isSettingsDrawer || isNavigationDrawerExpanded;
return isMobile
? isNavigationDrawerExpanded
: isSettingsDrawer || isNavigationDrawerExpanded;
};
@@ -1,10 +1,12 @@
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMetadataItem';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { PageLayoutLeftPanel } from '@/page-layout/components/PageLayoutLeftPanel';
import { PageLayoutTabList } from '@/page-layout/components/PageLayoutTabList';
import { PageLayoutTabListEffect } from '@/page-layout/components/PageLayoutTabListEffect';
import { DEFAULT_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultRecordPageLayoutId';
import { PAGE_LAYOUT_LEFT_PANEL_CONTAINER_WIDTH } from '@/page-layout/constants/PageLayoutLeftPanelContainerWidth';
import { WIDGET_TYPE_TO_RELATION_FIELD_NAME } from '@/page-layout/constants/WidgetTypeToRelationFieldName';
import { useCurrentPageLayoutOrThrow } from '@/page-layout/hooks/useCurrentPageLayoutOrThrow';
import { useIsPageLayoutInEditMode } from '@/page-layout/hooks/useIsPageLayoutInEditMode';
import { usePageLayoutAddTabStrategy } from '@/page-layout/hooks/usePageLayoutAddTabStrategy';
@@ -17,13 +19,17 @@ import { getTabsWithVisibleWidgets } from '@/page-layout/utils/getTabsWithVisibl
import { shouldEnableTabEditingFeatures } from '@/page-layout/utils/shouldEnableTabEditingFeatures';
import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
import { styled } from '@linaria/react';
import { useMemo } from 'react';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { useIsMobile } from 'twenty-ui/utilities';
const StyledContainer = styled.div<{ hasPinnedTab: boolean }>`
display: grid;
grid-template-columns: ${({ hasPinnedTab }) =>
@@ -69,6 +75,28 @@ export const PageLayoutTabsRenderer = () => {
currentPageLayout.id,
);
const targetRecord = useTargetRecord();
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular: targetRecord.targetObjectNameSingular,
});
const inactiveRelationFieldNames = useMemo(() => {
if (!isDefined(objectMetadataItem)) {
return new Set<string>();
}
return new Set(
objectMetadataItem.fields
.filter(
(field) =>
!field.isActive &&
(field.type === FieldMetadataType.RELATION ||
field.type === FieldMetadataType.MORPH_RELATION),
)
.map((field) => field.name),
);
}, [objectMetadataItem]);
const isMobile = useIsMobile();
const metadataStore = useAtomFamilyStateValue(
@@ -114,6 +142,22 @@ export const PageLayoutTabsRenderer = () => {
const sortedTabs = sortTabsByPosition(tabsToRenderInTabList);
const sortedActiveTabs = useMemo(
() =>
sortedTabs.filter((tab) => {
const widgetTypes = tab.widgets.map((widget) => widget.type);
return !widgetTypes.some((widgetType) => {
const relationFieldName =
WIDGET_TYPE_TO_RELATION_FIELD_NAME[widgetType];
return (
isDefined(relationFieldName) &&
inactiveRelationFieldNames.has(relationFieldName)
);
});
}),
[sortedTabs, inactiveRelationFieldNames],
);
const activeTabExistsInCurrentPageLayout = currentPageLayout.tabs.some(
(tab) => tab.id === activeTabId,
);
@@ -126,16 +170,16 @@ export const PageLayoutTabsRenderer = () => {
<StyledTabsAndDashboardContainer>
<PageLayoutTabListEffect
tabs={sortedTabs}
tabs={sortedActiveTabs}
componentInstanceId={tabListInstanceId}
defaultTabToFocusOnMobileAndSidePanelId={
currentPageLayout.defaultTabToFocusOnMobileAndSidePanelId ??
undefined
}
/>
{(sortedTabs.length > 1 || isPageLayoutInEditMode) && (
{(sortedActiveTabs.length > 1 || isPageLayoutInEditMode) && (
<PageLayoutTabList
tabs={sortedTabs}
tabs={sortedActiveTabs}
behaveAsLinks={!isInSidePanel && !isPageLayoutInEditMode}
isInSidePanel={isInSidePanel}
componentInstanceId={tabListInstanceId}
@@ -0,0 +1,12 @@
import { WidgetType } from '~/generated-metadata/graphql';
export const WIDGET_TYPE_TO_RELATION_FIELD_NAME: Partial<
Record<WidgetType, string>
> = {
[WidgetType.TASKS]: 'taskTargets',
[WidgetType.NOTES]: 'noteTargets',
[WidgetType.FILES]: 'attachments',
[WidgetType.TIMELINE]: 'timelineActivities',
[WidgetType.EMAILS]: 'messageParticipants',
[WidgetType.CALENDAR]: 'calendarEventParticipants',
};
@@ -1,9 +0,0 @@
import { gql } from '@apollo/client';
export const PERMISSION_FLAG_FRAGMENT = gql`
fragment PermissionFlagFragment on PermissionFlag {
id
flag
roleId
}
`;
@@ -0,0 +1,9 @@
import { gql } from '@apollo/client';
export const ROLE_PERMISSION_FLAG_FRAGMENT = gql`
fragment RolePermissionFlagFragment on RolePermissionFlag {
id
flag
roleId
}
`;
@@ -1,15 +1,15 @@
import { PERMISSION_FLAG_FRAGMENT } from '@/settings/roles/graphql/fragments/permissionFlagFragment';
import { ROLE_PERMISSION_FLAG_FRAGMENT } from '@/settings/roles/graphql/fragments/rolePermissionFlagFragment';
import { gql } from '@apollo/client';
export const UPSERT_PERMISSION_FLAGS = gql`
${PERMISSION_FLAG_FRAGMENT}
${ROLE_PERMISSION_FLAG_FRAGMENT}
mutation UpsertPermissionFlags(
$upsertPermissionFlagsInput: UpsertPermissionFlagsInput!
) {
upsertPermissionFlags(
upsertPermissionFlagsInput: $upsertPermissionFlagsInput
) {
...PermissionFlagFragment
...RolePermissionFlagFragment
}
}
`;
@@ -2,7 +2,7 @@ import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
import { API_KEY_FOR_ROLE_FRAGMENT } from '@/settings/roles/graphql/fragments/apiKeyForRoleFragment';
import { FIELD_PERMISSION_FRAGMENT } from '@/settings/roles/graphql/fragments/fieldPermissionFragment';
import { OBJECT_PERMISSION_FRAGMENT } from '@/settings/roles/graphql/fragments/objectPermissionFragment';
import { PERMISSION_FLAG_FRAGMENT } from '@/settings/roles/graphql/fragments/permissionFlagFragment';
import { ROLE_PERMISSION_FLAG_FRAGMENT } from '@/settings/roles/graphql/fragments/rolePermissionFlagFragment';
import { ROLE_FRAGMENT } from '@/settings/roles/graphql/fragments/roleFragment';
import { ROW_LEVEL_PERMISSION_PREDICATE_FRAGMENT } from '@/settings/roles/graphql/fragments/rowLevelPermissionPredicateFragment';
import { ROW_LEVEL_PERMISSION_PREDICATE_GROUP_FRAGMENT } from '@/settings/roles/graphql/fragments/rowLevelPermissionPredicateGroupFragment';
@@ -14,7 +14,7 @@ export const GET_ROLES = gql`
${ROLE_FRAGMENT}
${AGENT_FRAGMENT}
${API_KEY_FOR_ROLE_FRAGMENT}
${PERMISSION_FLAG_FRAGMENT}
${ROLE_PERMISSION_FLAG_FRAGMENT}
${OBJECT_PERMISSION_FRAGMENT}
${FIELD_PERMISSION_FRAGMENT}
${ROW_LEVEL_PERMISSION_PREDICATE_FRAGMENT}
@@ -32,7 +32,7 @@ export const GET_ROLES = gql`
...ApiKeyForRoleFragment
}
permissionFlags {
...PermissionFlagFragment
...RolePermissionFlagFragment
}
objectPermissions {
...ObjectPermissionFragment
@@ -6,16 +6,18 @@ import {
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
export const useHasPermissionFlag = (permissionFlag?: PermissionFlagType) => {
export const useHasPermissionFlag = (
permissionFlagKey?: PermissionFlagType,
) => {
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
const currentUserWorkspace = useAtomStateValue(currentUserWorkspaceState);
if (!permissionFlag) {
if (!permissionFlagKey) {
return true;
}
if (
permissionFlag === PermissionFlagType.WORKSPACE &&
permissionFlagKey === PermissionFlagType.WORKSPACE &&
currentWorkspace?.activationStatus ===
WorkspaceActivationStatus.PENDING_CREATION
) {
@@ -23,5 +25,5 @@ export const useHasPermissionFlag = (permissionFlag?: PermissionFlagType) => {
}
const userFlags = currentUserWorkspace?.permissionFlags ?? [];
return userFlags.includes(permissionFlag);
return userFlags.includes(permissionFlagKey);
};
@@ -29,6 +29,7 @@ export const StyledPageInfoTextContainer = styled.div`
`;
export const StyledPageInfoTitleContainer = styled.div`
color: ${themeCssVariables.font.color.primary};
font-size: ${themeCssVariables.font.size.md};
font-weight: ${themeCssVariables.font.weight.semiBold};
max-width: 150px;
@@ -1,6 +1,9 @@
import { useContext, useId, useState } from 'react';
import { createPortal } from 'react-dom';
import { styled } from '@linaria/react';
import { AppTooltip, TooltipDelay, TooltipPosition } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { isDefined, formatToShortNumber } from 'twenty-shared/utils';
import { useNumberFormat } from '@/localization/hooks/useNumberFormat';
import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition';
@@ -10,10 +13,13 @@ import {
} from '@/object-record/record-field/ui/types/FieldMetadata';
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { isDefined, formatToShortNumber } from 'twenty-shared/utils';
import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledCurrencyIconContainer = styled.span`
align-items: center;
display: flex;
`;
type CurrencyDisplayProps = {
currencyValue: FieldCurrencyValue | null | undefined;
@@ -57,7 +63,7 @@ export const CurrencyDisplay = ({
<EllipsisDisplay>
{shouldShowCurrencyTooltip && (
<>
<span
<StyledCurrencyIconContainer
id={tooltipAnchorId}
onMouseEnter={() => setShouldRenderTooltip(true)}
onMouseLeave={() => setShouldRenderTooltip(false)}
@@ -67,7 +73,7 @@ export const CurrencyDisplay = ({
size={theme.icon.size.md}
stroke={theme.icon.stroke.sm}
/>
</span>{' '}
</StyledCurrencyIconContainer>{' '}
</>
)}
{amountToDisplay !== null
@@ -48,6 +48,7 @@ const StyledPageContainerBase = styled.div`
flex: 1 1 auto;
flex-direction: row;
min-height: 0;
min-width: 0;
`;
const StyledPageContainer = motion.create(StyledPageContainerBase);
@@ -58,6 +59,7 @@ const StyledNavigationDrawerWrapper = styled.div`
const StyledMainContainer = styled.div`
display: flex;
flex: 0 1 100%;
min-width: 0;
overflow: hidden;
`;
@@ -2,7 +2,7 @@ import { styled } from '@linaria/react';
import { type ReactNode } from 'react';
import { PagePanel } from './PagePanel';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
type PageBodyProps = {
children: ReactNode;
@@ -21,6 +21,10 @@ const StyledMainContainer = styled.div`
padding-left: 0;
padding-right: ${themeCssVariables.spacing[3]};
width: 100%;
@media (max-width: ${MOBILE_VIEWPORT}px) {
padding-left: ${themeCssVariables.spacing[3]};
}
`;
type LeftContainerProps = {
@@ -3,6 +3,7 @@ import { type ReactNode, useContext } from 'react';
import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton';
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
import { useNavigationDrawerExpanded } from '@/navigation/hooks/useNavigationDrawerExpanded';
import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constants/PageActionContainerClickOutsideId';
import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight';
@@ -104,6 +105,7 @@ export const PageHeader = ({
className,
}: PageHeaderProps) => {
const isMobile = useIsMobile();
const isSettingsPage = useIsSettingsPage();
const { theme } = useContext(ThemeContext);
const isNavigationDrawerExpanded = useNavigationDrawerExpanded();
@@ -111,7 +113,7 @@ export const PageHeader = ({
<AnimatePresence initial={false}>
<StyledTopBarContainer className={className} isMobile={isMobile}>
<StyledLeftContainer>
{!isMobile && !isNavigationDrawerExpanded && (
{!isNavigationDrawerExpanded && (!isMobile || isSettingsPage) && (
<NavigationDrawerCollapseButton direction="right" />
)}
{hasClosePageButton && (
@@ -1,5 +1,5 @@
import { t } from '@lingui/core/macro';
import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings';
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
import { styled } from '@linaria/react';
import { isNonEmptyString } from '@sniptt/guards';
import { type ReactNode, useContext } from 'react';
@@ -47,14 +47,13 @@ export const MobileBreadcrumb = ({
links,
}: MobileBreadcrumbProps) => {
const { theme } = useContext(ThemeContext);
const { openSettingsMenu } = useOpenSettingsMenu();
const isSettingsPage = useIsSettingsPage();
const handleBackToSettingsClick = () => {
openSettingsMenu();
};
if (isSettingsPage && links.length <= 2) {
return null;
}
const previousLink = links[links.length - 2];
const shouldRedirectToSettings = links.length === 2;
const text = isNonEmptyString(previousLink.children)
? previousLink.children
@@ -64,14 +63,7 @@ export const MobileBreadcrumb = ({
return (
<StyledWrapper className={className}>
{shouldRedirectToSettings ? (
<>
<IconChevronLeft size={theme.icon.size.md} />
<StyledText onClick={handleBackToSettingsClick}>
{t`Back to Settings`}
</StyledText>
</>
) : previousLink?.href ? (
{previousLink?.href ? (
<>
<IconChevronLeft size={theme.icon.size.md} />
<StyledLinkContainer>
@@ -47,13 +47,12 @@ const StyledAnimatedContainer = styled.div<{
: `${NAVIGATION_DRAWER_COLLAPSED_WIDTH}px`};
@media (max-width: ${MOBILE_VIEWPORT}px) {
width: ${({ isExpanded }) => (isExpanded ? '100%' : '0')};
width: ${({ isExpanded }) => (isExpanded ? '100vw' : '0')};
}
`;
const StyledContainer = styled.div<{
isSettings?: boolean;
isMobile?: boolean;
isExpanded?: boolean;
}>`
box-sizing: border-box;
@@ -61,18 +60,17 @@ const StyledContainer = styled.div<{
flex-direction: column;
gap: ${themeCssVariables.spacing[3]};
height: 100%;
padding: ${({ isSettings, isMobile }) =>
padding: ${({ isSettings }) =>
isSettings
? isMobile
? `${themeCssVariables.spacing[3]} 0 0 ${themeCssVariables.spacing[8]}`
: `${themeCssVariables.spacing[3]} 0 ${themeCssVariables.spacing[4]} 0`
? `${themeCssVariables.spacing[3]} 0 ${themeCssVariables.spacing[4]} 0`
: `${themeCssVariables.spacing[3]} 0 ${themeCssVariables.spacing[4]} ${themeCssVariables.spacing[2]}`};
width: ${({ isExpanded }) =>
isExpanded ? `var(${NAVIGATION_DRAWER_WIDTH_VAR})` : '100%'};
@media (max-width: ${MOBILE_VIEWPORT}px) {
gap: ${themeCssVariables.spacing[4]};
width: 100%;
padding-left: ${themeCssVariables.spacing[5]};
padding-right: ${themeCssVariables.spacing[5]};
padding-left: ${themeCssVariables.spacing[2]};
padding-right: ${themeCssVariables.spacing[2]};
}
`;
@@ -125,12 +123,8 @@ export const NavigationDrawer = ({
isExpanded={isExpanded}
isResizing={isResizing}
>
<StyledContainer
isSettings={isSettingsDrawer}
isMobile={isMobile}
isExpanded={isExpanded}
>
{isSettingsDrawer && title ? (
<StyledContainer isSettings={isSettingsDrawer} isExpanded={isExpanded}>
{!isMobile && isSettingsDrawer && title ? (
<NavigationDrawerBackButton title={title} />
) : (
<NavigationDrawerHeader showCollapseButton />
@@ -10,14 +10,14 @@ const StyledFixedContainer = styled.div<{
isSettings?: boolean;
isMobile?: boolean;
}>`
padding-left: ${({ isSettings }) =>
isSettings ? themeCssVariables.spacing[5] : '0'};
padding-left: ${({ isSettings, isMobile }) =>
isSettings || isMobile ? themeCssVariables.spacing[5] : '0'};
padding-right: ${({ isSettings, isMobile }) =>
isSettings
? isMobile
? themeCssVariables.spacing[5]
: themeCssVariables.spacing[8]
: '0'};
isMobile
? themeCssVariables.spacing[5]
: isSettings
? themeCssVariables.spacing[8]
: '0'};
`;
export const NavigationDrawerFixedContent = ({
children,
@@ -2,7 +2,7 @@ import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { IconSearch } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
import { useOpenRecordsSearchPageInSidePanel } from '@/side-panel/hooks/useOpenRecordsSearchPageInSidePanel';
import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight';
@@ -21,6 +21,11 @@ const StyledContainer = styled.div<{ isExpanded: boolean }>`
padding-right: ${themeCssVariables.spacing[2]};
transition: gap calc(${themeCssVariables.animation.duration.normal} * 1s) ease;
user-select: none;
@media (max-width: ${MOBILE_VIEWPORT}px) {
padding-left: ${themeCssVariables.spacing[5]};
padding-right: ${themeCssVariables.spacing[5]};
}
`;
const StyledRightActions = styled.div<{ isExpanded: boolean }>`
@@ -40,6 +45,14 @@ const StyledNavigationDrawerCollapseButtonContainer = styled.div`
padding-right: ${themeCssVariables.spacing[1]};
width: ${themeCssVariables.spacing[6]};
}
@media (max-width: ${MOBILE_VIEWPORT}px) {
> * {
height: ${themeCssVariables.spacing[8]};
padding-right: 0;
width: ${themeCssVariables.spacing[8]};
}
}
`;
const StyledWorkspaceDropdownContainer = styled.div`
@@ -68,8 +81,8 @@ export const NavigationDrawerHeader = ({
<StyledWorkspaceDropdownContainer>
<MultiWorkspaceDropdownButton />
</StyledWorkspaceDropdownContainer>
{!isMobile && (
<StyledRightActions isExpanded={isNavigationDrawerExpanded}>
<StyledRightActions isExpanded={isNavigationDrawerExpanded}>
{!isMobile && (
<LightIconButton
Icon={IconSearch}
accent="secondary"
@@ -77,13 +90,13 @@ export const NavigationDrawerHeader = ({
onClick={openRecordsSearchPage}
aria-label={t`Search`}
/>
{isNavigationDrawerExpanded && showCollapseButton && (
<StyledNavigationDrawerCollapseButtonContainer>
<NavigationDrawerCollapseButton direction="left" />
</StyledNavigationDrawerCollapseButtonContainer>
)}
</StyledRightActions>
)}
)}
{isNavigationDrawerExpanded && showCollapseButton && (
<StyledNavigationDrawerCollapseButtonContainer>
<NavigationDrawerCollapseButton direction="left" />
</StyledNavigationDrawerCollapseButtonContainer>
)}
</StyledRightActions>
</StyledContainer>
);
};

Some files were not shown because too many files have changed in this diff Show More