Merge branch 'main' into claude/billing-events-analytics-cnHak
This commit is contained in:
@@ -100,7 +100,7 @@ jobs:
|
||||
create-twenty-app --version
|
||||
mkdir -p /tmp/e2e-test-workspace
|
||||
cd /tmp/e2e-test-workspace
|
||||
create-twenty-app test-app --exhaustive --display-name "Test App" --description "E2E test app"
|
||||
create-twenty-app test-app --exhaustive --display-name "Test App" --description "E2E test app" --skip-local-instance
|
||||
|
||||
- name: Install scaffolded app dependencies
|
||||
run: |
|
||||
|
||||
@@ -27,6 +27,10 @@ const program = new Command(packageJson.name)
|
||||
'--description <description>',
|
||||
'Application description (skips prompt)',
|
||||
)
|
||||
.option(
|
||||
'--skip-local-instance',
|
||||
'Skip the local Twenty instance setup prompt',
|
||||
)
|
||||
.helpOption('-h, --help', 'Display this help message.')
|
||||
.action(
|
||||
async (
|
||||
@@ -37,6 +41,7 @@ const program = new Command(packageJson.name)
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
skipLocalInstance?: boolean;
|
||||
},
|
||||
) => {
|
||||
const modeFlags = [options?.exhaustive, options?.minimal].filter(Boolean);
|
||||
@@ -72,6 +77,7 @@ const program = new Command(packageJson.name)
|
||||
name: options?.name,
|
||||
displayName: options?.displayName,
|
||||
description: options?.description,
|
||||
skipLocalInstance: options?.skipLocalInstance,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { copyBaseApplicationProject } from '@/utils/app-template';
|
||||
import { convertToLabel } from '@/utils/convert-to-label';
|
||||
import { install } from '@/utils/install';
|
||||
import {
|
||||
type LocalInstanceResult,
|
||||
setupLocalInstance,
|
||||
} from '@/utils/setup-local-instance';
|
||||
import { tryGitInit } from '@/utils/try-git-init';
|
||||
import chalk from 'chalk';
|
||||
import * as fs from 'fs-extra';
|
||||
import inquirer from 'inquirer';
|
||||
import kebabCase from 'lodash.kebabcase';
|
||||
import { execSync } from 'node:child_process';
|
||||
import * as path from 'path';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -22,6 +27,7 @@ type CreateAppOptions = {
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
skipLocalInstance?: boolean;
|
||||
};
|
||||
|
||||
export class CreateAppCommand {
|
||||
@@ -52,7 +58,29 @@ export class CreateAppCommand {
|
||||
|
||||
await tryGitInit(appDirectory);
|
||||
|
||||
this.logSuccess(appDirectory);
|
||||
let localResult: LocalInstanceResult = { running: false };
|
||||
|
||||
if (!options.skipLocalInstance) {
|
||||
const { needsLocalInstance } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'needsLocalInstance',
|
||||
message:
|
||||
'Do you need a local instance of Twenty? Recommended if you not have one already.',
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
if (needsLocalInstance) {
|
||||
localResult = await setupLocalInstance();
|
||||
}
|
||||
|
||||
if (isDefined(localResult.apiKey)) {
|
||||
this.runAuthLogin(appDirectory, localResult.apiKey);
|
||||
}
|
||||
}
|
||||
|
||||
this.logSuccess(appDirectory, localResult);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Initialization failed:'),
|
||||
@@ -179,20 +207,49 @@ export class CreateAppCommand {
|
||||
console.log('');
|
||||
}
|
||||
|
||||
private logSuccess(appDirectory: string): void {
|
||||
private runAuthLogin(appDirectory: string, apiKey: string): void {
|
||||
try {
|
||||
execSync(
|
||||
`yarn twenty auth:login --api-key "${apiKey}" --api-url http://localhost:3000`,
|
||||
{ cwd: appDirectory, stdio: 'inherit' },
|
||||
);
|
||||
console.log(chalk.green('✅ Authenticated with local Twenty instance.'));
|
||||
} catch {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ Auto auth:login failed. Run `yarn twenty auth:login` manually.',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private logSuccess(
|
||||
appDirectory: string,
|
||||
localResult: LocalInstanceResult,
|
||||
): void {
|
||||
const dirName = appDirectory.split('/').reverse()[0] ?? '';
|
||||
|
||||
console.log(chalk.green('✅ Application created!'));
|
||||
console.log('');
|
||||
console.log(chalk.blue('Next steps:'));
|
||||
console.log(chalk.gray(` cd ${dirName}`));
|
||||
console.log(
|
||||
chalk.gray(
|
||||
' yarn twenty remote add --local # Authenticate with Twenty',
|
||||
),
|
||||
);
|
||||
console.log(
|
||||
chalk.gray(' yarn twenty dev # Start dev mode'),
|
||||
);
|
||||
|
||||
if (localResult.apiKey) {
|
||||
console.log(chalk.gray(' yarn twenty app:dev # Start dev mode'));
|
||||
} else if (localResult.running) {
|
||||
console.log(
|
||||
chalk.gray(
|
||||
' yarn twenty remote add --local # Authenticate with Twenty',
|
||||
),
|
||||
);
|
||||
console.log(chalk.gray(' yarn twenty app:dev # Start dev mode'));
|
||||
} else {
|
||||
console.log(
|
||||
chalk.gray(
|
||||
' yarn twenty remote add --local # Authenticate with Twenty',
|
||||
),
|
||||
);
|
||||
console.log(chalk.gray(' yarn twenty app:dev # Start dev mode'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import { execSync } from 'node:child_process';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const INSTALL_SCRIPT_URL =
|
||||
'https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh';
|
||||
|
||||
const SERVER_CONTAINER = 'twenty-server-1';
|
||||
const DB_CONTAINER = 'twenty-db-1';
|
||||
|
||||
const isDockerAvailable = (): boolean => {
|
||||
try {
|
||||
execSync('docker compose version', { stdio: 'ignore' });
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const isDockerRunning = (): boolean => {
|
||||
try {
|
||||
execSync('docker info', { stdio: 'ignore' });
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const isTwentyServerRunning = async (): Promise<boolean> => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 3000);
|
||||
|
||||
const response = await fetch('http://localhost:3000/healthz', {
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
const body = await response.json();
|
||||
|
||||
return body.status === 'ok';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getActiveWorkspaceId = (): string | null => {
|
||||
try {
|
||||
const result = execSync(
|
||||
`docker exec ${DB_CONTAINER} psql -U postgres -d default -t -c "SELECT id FROM core.workspace WHERE \\"activationStatus\\" = 'ACTIVE' LIMIT 1"`,
|
||||
{ encoding: 'utf-8' },
|
||||
).trim();
|
||||
|
||||
return result || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const generateApiKeyToken = (workspaceId: string): string | null => {
|
||||
try {
|
||||
const output = execSync(
|
||||
`docker exec -e NODE_ENV=development ${SERVER_CONTAINER} yarn command:prod workspace:generate-api-key -w ${workspaceId}`,
|
||||
{ encoding: 'utf-8' },
|
||||
);
|
||||
|
||||
const TOKEN_PREFIX = 'TOKEN:';
|
||||
const tokenLine = output
|
||||
.trim()
|
||||
.split('\n')
|
||||
.find((line) => line.includes(TOKEN_PREFIX));
|
||||
|
||||
if (!tokenLine) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tokenStartIndex =
|
||||
tokenLine.indexOf(TOKEN_PREFIX) + TOKEN_PREFIX.length;
|
||||
|
||||
return tokenLine.slice(tokenStartIndex).trim();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export type LocalInstanceResult = {
|
||||
running: boolean;
|
||||
apiKey?: string;
|
||||
};
|
||||
|
||||
export const setupLocalInstance = async (): Promise<LocalInstanceResult> => {
|
||||
console.log('');
|
||||
console.log(chalk.blue('🐳 Setting up local Twenty instance...'));
|
||||
|
||||
if (await isTwentyServerRunning()) {
|
||||
console.log(
|
||||
chalk.green('✅ Twenty server is already running on localhost:3000.'),
|
||||
);
|
||||
} else {
|
||||
if (!isDockerAvailable()) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ Docker Compose is not installed. Please install Docker first.',
|
||||
),
|
||||
);
|
||||
console.log(chalk.gray(' See https://docs.docker.com/get-docker/'));
|
||||
|
||||
return { running: false };
|
||||
}
|
||||
|
||||
if (!isDockerRunning()) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ Docker is not running. Please start Docker and try again.',
|
||||
),
|
||||
);
|
||||
|
||||
return { running: false };
|
||||
}
|
||||
|
||||
try {
|
||||
execSync(`bash <(curl -sL ${INSTALL_SCRIPT_URL})`, {
|
||||
stdio: 'inherit',
|
||||
shell: '/bin/bash',
|
||||
});
|
||||
} catch {
|
||||
console.log(
|
||||
chalk.yellow('⚠️ Local instance setup did not complete successfully.'),
|
||||
);
|
||||
|
||||
return { running: false };
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log(
|
||||
chalk.blue(
|
||||
'👉 Please create your workspace in the browser before continuing.',
|
||||
),
|
||||
);
|
||||
|
||||
const { workspaceCreated } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'workspaceCreated',
|
||||
message: 'Have you finished creating your workspace?',
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!workspaceCreated) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ Skipping API key generation. Run `yarn twenty remote add --local` manually after creating your workspace.',
|
||||
),
|
||||
);
|
||||
|
||||
return { running: true };
|
||||
}
|
||||
|
||||
console.log(chalk.blue('🔑 Generating API key for your workspace...'));
|
||||
|
||||
const workspaceId = getActiveWorkspaceId();
|
||||
|
||||
if (!isDefined(workspaceId)) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ No active workspace found. Make sure you completed the signup flow, then run `yarn twenty auth:login` manually.',
|
||||
),
|
||||
);
|
||||
|
||||
return { running: true };
|
||||
}
|
||||
|
||||
const apiKey = generateApiKeyToken(workspaceId);
|
||||
|
||||
if (!isDefined(apiKey)) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'⚠️ Could not generate API key. Run `yarn twenty auth:login` manually.',
|
||||
),
|
||||
);
|
||||
|
||||
return { running: true };
|
||||
}
|
||||
|
||||
console.log(chalk.green('✅ API key generated for your workspace.'));
|
||||
|
||||
return { running: true, apiKey };
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
@@ -2559,13 +2559,11 @@ msgstr "Kan nie skandeer nie? Kopieer die"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Kanselleer"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Kanselleer uitgawe"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Kon nie prent verwyder nie"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Kon nie werke herprobeer nie. Probeer asseblief later weer."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Uitleg"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Saterdag"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Stoor"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Stoor as nuwe aansig"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Stoor Paneelbord"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Sommige"
|
||||
msgid "Some folders"
|
||||
msgstr "Sommige vouers"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "هل لا يمكنك المسح؟ انسخ الـ"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "إلغاء التعديل"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "فشل في إزالة الصورة"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "فشل في إعادة محاولة الوظائف. يُرجى المحاولة مرة أخرى لاحقًا."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "التخطيط"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "السبت"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "حفظ"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "احفظ كعرض جديد"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "حفظ لوحة القيادة"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "بعض"
|
||||
msgid "Some folders"
|
||||
msgstr "بعض المجلدات"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "No pots escanejar? Copia la"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel·la"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Cancel·la l'edició"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "No s'ha pogut eliminar la imatge"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Error en reintentar feines. Torneu-ho a provar més tard."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Disseny"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Dissabte"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Desa"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Desa com a nova vista"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Desa el quadre de comandament"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Alguns"
|
||||
msgid "Some folders"
|
||||
msgstr "Algunes carpetes"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Nemůžete skenovat? Zkopírujte"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Storno"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Zrušit edici"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Nepodařilo se odstranit obrázek"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Nepodařilo se znovu spustit úlohy. Prosím, zkuste to znovu později."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Rozvržení"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sobota"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Uložit"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Uložit jako nové zobrazení"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Uložit panel"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Některé"
|
||||
msgid "Some folders"
|
||||
msgstr "Některé složky"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Kan ikke scanne? Kopier"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annuller"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Annuller udgave"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Kunne ikke fjerne billede"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Kunne ikke forsøge jobs igen. Prøv venligst igen senere."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Lørdag"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Gem"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Gem som ny visning"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Gem dashboard"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Nogle"
|
||||
msgid "Some folders"
|
||||
msgstr "Nogle mapper"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Kann nicht gescannt werden? Kopieren Sie das"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Edition abbrechen"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Bild konnte nicht entfernt werden"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Aufgaben konnten nicht erneut versucht werden. Bitte versuchen Sie es später noch einmal."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Samstag"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Als neue Ansicht speichern"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Dashboard speichern"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Einige"
|
||||
msgid "Some folders"
|
||||
msgstr "Einige Ordner"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Δεν μπορείτε να σαρώσετε; Αντιγράψτε το
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Ακύρωση"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Ακύρωση Έκδοσης"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Αποτυχία αφαίρεσης εικόνας"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Αποτυχία επαναποστολής εργασιών. Παρακαλώ δοκιμάστε ξανά αργότερα."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Διάταξη"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Σάββατο"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Αποθήκευση"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Αποθήκευση ως νέα προβολή"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Αποθήκευση πίνακα ελέγχου"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12642,6 +12634,11 @@ msgstr "Μερικά"
|
||||
msgid "Some folders"
|
||||
msgstr "Ορισμένοι φάκελοι"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2554,13 +2554,11 @@ msgstr "Can't scan? Copy the"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Cancel Edition"
|
||||
@@ -6182,10 +6180,10 @@ msgstr "Failed to remove picture"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Failed to retry jobs. Please try again later."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
msgstr "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr "Failed to save layout customization"
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
#: src/pages/settings/ai/SettingsAgentForm.tsx
|
||||
@@ -8016,7 +8014,7 @@ msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr "Layout customization"
|
||||
|
||||
@@ -11577,7 +11575,6 @@ msgstr "Saturday"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Save"
|
||||
@@ -11592,11 +11589,6 @@ msgstr "Save as new view"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Save Dashboard"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr "Save Page Layout"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12635,6 +12627,11 @@ msgstr "Some"
|
||||
msgid "Some folders"
|
||||
msgstr "Some folders"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr "Some layout changes could not be saved"
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "¿No puedes escanear? Copia el"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Cancelar edición"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "No se pudo eliminar la imagen"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "No se pudieron reintentar los trabajos. Por favor, inténtelo de nuevo más tarde."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Diseño"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sábado"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Guardar como nueva vista"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Guardar Tablero"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Alguno"
|
||||
msgid "Some folders"
|
||||
msgstr "Algunas carpetas"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Et voi skannata? Kopioi"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Peruuta"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Peruuta muokkaus"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Kuvan poistaminen epäonnistui"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Epäonnistui uusien tehtävien yrittämisessä. Yritä myöhemmin uudelleen."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Ulkoasu"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Lauantai"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Tallenna"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Tallenna uutena näkymänä"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Tallenna hallintapaneeli"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Jotkut"
|
||||
msgid "Some folders"
|
||||
msgstr "Jotkin kansiot"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Impossible de scanner ? Copiez le"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Annuler l'édition"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Échec de la suppression de l'image"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Échec du réessai des tâches. Veuillez réessayer plus tard."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Disposition"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Samedi"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Enregistrer comme nouvelle vue"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Enregistrer le tableau de bord"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Certains"
|
||||
msgid "Some folders"
|
||||
msgstr "Certains dossiers"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
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
@@ -2559,13 +2559,11 @@ msgstr "לא ניתן לסרוק? העתק את"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "בטל"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "בטל עריכה"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "הסרת התמונה נכשלה"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "נכשל בהפעלה מחדש של עבודות. נא לנסות שוב מאוחר יותר."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "פריסה"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "יום שבת"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "שמור"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "שמור כתצוגה חדשה"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "שמור לוח בקרה"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "חלק"
|
||||
msgid "Some folders"
|
||||
msgstr "כמה תיקיות"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Nem tud beolvasni? Másolja a"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Mégse"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Szerkesztés törlése"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Nem sikerült eltávolítani a képet"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Nem sikerült újraindítani az állásokat. Kérjük, próbálja meg újra később."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Elrendezés"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Szombat"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Mentés"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Mentés új nézetként"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Irányítópult mentése"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Néhány"
|
||||
msgid "Some folders"
|
||||
msgstr "Néhány mappa"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Non puoi scansionare? Copia il"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annulla"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Annulla Edizione"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Impossibile rimuovere l'immagine"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Impossibile riprovare i lavori. Per favore riprova più tardi."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Disposizione"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sabato"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Salva come nuova vista"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Salva Cruscotto"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Alcuni"
|
||||
msgid "Some folders"
|
||||
msgstr "Alcune cartelle"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "スキャンできませんか? コピーしてください"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "編集をキャンセル"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "画像を削除できませんでした"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "ジョブの再試行に失敗しました。後でもう一度お試しください。"
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "レイアウト"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "土曜日"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "新しいビューとして保存"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "ダッシュボードを保存"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "一部"
|
||||
msgid "Some folders"
|
||||
msgstr "いくつかのフォルダー"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "스캔이 불가능합니까?"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "취소"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "판 취소"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "사진 제거 실패"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "작업 재시도 실패. 나중에 다시 시도하세요."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "레이아웃"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "토요일"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "저장"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "새 보기로 저장"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "대시보드 저장"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "일부"
|
||||
msgid "Some folders"
|
||||
msgstr "일부 폴더"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Kan je niet scannen? Kopieer de"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Annuleer Bewerken"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Het verwijderen van de afbeelding is mislukt"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Fout bij het opnieuw proberen van taken. Probeer het later opnieuw."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Lay-out"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Zaterdag"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Opslaan"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Opslaan als nieuwe weergave"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Dashboard opslaan"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Enkele"
|
||||
msgid "Some folders"
|
||||
msgstr "Sommige mappen"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Kan ikke skanne? Kopier "
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Avbryt redigering"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Kunne ikke fjerne bilde"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Mislyktes å prøve jobber på nytt. Vennligst prøv igjen senere."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Oppsett"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Lørdag"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Lagre"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Lagre som ny visning"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Lagre dashbord"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Noen"
|
||||
msgid "Some folders"
|
||||
msgstr "Noen mapper"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Nie można zeskanować? Skopiuj"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Anuluj"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Anuluj edycję"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Nie udało się usunąć zdjęcia"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Nie udało się ponowić zadań. Proszę spróbować ponownie później."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Układ"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sobota"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Zapisz"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Zapisz jako nowy widok"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Zapisz Dashboard"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Niektóre"
|
||||
msgid "Some folders"
|
||||
msgstr "Niektóre foldery"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2554,13 +2554,11 @@ msgstr ""
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr ""
|
||||
@@ -6182,9 +6180,9 @@ msgstr ""
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8016,7 +8014,7 @@ msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11577,7 +11575,6 @@ msgstr ""
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
@@ -11592,11 +11589,6 @@ msgstr ""
|
||||
msgid "Save Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12635,6 +12627,11 @@ msgstr ""
|
||||
msgid "Some folders"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Não consegue escanear? Copie o"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Cancelar Edição"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Falha ao remover imagem"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Falha ao repetir trabalhos. Por favor, tente novamente mais tarde."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Disposição"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sábado"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Salvar"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Salvar como nova visualização"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Salvar Painel"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Alguns"
|
||||
msgid "Some folders"
|
||||
msgstr "Algumas pastas"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Não consegue escanear? Copie o"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Cancelar Edição"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Falha ao remover a imagem"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Falha ao reiniciar trabalhos. Por favor, tente novamente mais tarde."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sábado"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Salvar"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Salvar como nova vista"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Salvar Painel"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Alguns"
|
||||
msgid "Some folders"
|
||||
msgstr "Algumas pastas"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Nu poți scana? Copiază"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Anulare"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Anulează ediția"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Nu s-a reușit eliminarea imaginii"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Eșuat la reîncercarea locurilor de muncă. Încercați din nou mai târziu."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Aspect"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Sâmbătă"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Salvează"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Salvează ca nouă vizualizare"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Salvează tabloul de bord"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Câteva"
|
||||
msgid "Some folders"
|
||||
msgstr "Unele foldere"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
Binary file not shown.
@@ -2559,13 +2559,11 @@ msgstr "Не можете да скенирате? Копирајте"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Откажи"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Откажи издање"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Није успело уклањање слике"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Није успело понављање послова. Покушајте поново касније."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Изглед"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Субота"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Сачувај"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Сачувај као ново приказ"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Сачувај контролну таблу"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Неки"
|
||||
msgid "Some folders"
|
||||
msgstr "Неке фасцикле"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Kan inte skanna? Kopiera "
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Avbryt utgåva"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Misslyckades med att ta bort bild"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Det gick inte att återsöka jobben. Försök igen senare."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11586,7 +11584,6 @@ msgstr ""
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Spara"
|
||||
@@ -11601,11 +11598,6 @@ msgstr "Spara som ny vy"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Spara instrumentpanel"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12644,6 +12636,11 @@ msgstr "Vissa"
|
||||
msgid "Some folders"
|
||||
msgstr "Vissa mappar"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Tarayamaz mısınız? Kopyalayın."
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "İptal"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Sürümü İptal Et"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Resim kaldırılamadı"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "İşleri yeniden deneme başarısız oldu. Lütfen daha sonra tekrar deneyiniz."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Düzen"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Cumartesi"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Kaydet"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Yeni görünüm olarak kaydet"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Gösterge Panelini Kaydet"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Bazı"
|
||||
msgid "Some folders"
|
||||
msgstr "Bazı klasörler"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Не можете сканувати? Скопіюйте"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Скасувати"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Скасувати редакцію"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Не вдалося видалити зображення"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Не вдалося повторити завдання. Будь ласка, спробуйте пізніше."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Макет"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Субота"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Зберегти"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Зберегти як новий перегляд"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Зберегти інформаційну панель"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Деякі"
|
||||
msgid "Some folders"
|
||||
msgstr "Деякі папки"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "Không thể quét? Sao chép"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Hủy bỏ"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "Hủy chỉnh sửa"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "Không thể xóa ảnh"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "Không thể thử lại các công việc. Vui lòng thử lại sau."
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "Bố cục"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "Thứ Bảy"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "Lưu"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "Lưu dưới dạng chế độ xem mới"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "Lưu bảng điều khiển"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "Một số"
|
||||
msgid "Some folders"
|
||||
msgstr "Một số thư mục"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "无法扫描?复制"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "取消版本"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "移除图片失败"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "重试任务失败。请稍后再试。"
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "布局"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "星期六"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "另存为新视图"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "保存仪表板"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "一些"
|
||||
msgid "Some folders"
|
||||
msgstr "某些文件夹"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
@@ -2559,13 +2559,11 @@ msgstr "無法掃描? 複製"
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#. js-lingui-id: HYLdMN
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Cancel Edition"
|
||||
msgstr "取消編輯"
|
||||
@@ -6187,9 +6185,9 @@ msgstr "移除圖片失敗"
|
||||
msgid "Failed to retry jobs. Please try again later."
|
||||
msgstr "無法重試工作。請稍後重試。"
|
||||
|
||||
#. js-lingui-id: fuRtgB
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
msgid "Failed to save navigation layout"
|
||||
#. js-lingui-id: farFvy
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Failed to save layout customization"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: y3HIOa
|
||||
@@ -8021,7 +8019,7 @@ msgid "Layout"
|
||||
msgstr "版面設計"
|
||||
|
||||
#. js-lingui-id: W4nIBb
|
||||
#: src/modules/navigation-menu-item/edit/components/NavigationMenuEditModeBar.tsx
|
||||
#: src/modules/layout-customization/components/LayoutCustomizationBar.tsx
|
||||
msgid "Layout customization"
|
||||
msgstr ""
|
||||
|
||||
@@ -11582,7 +11580,6 @@ msgstr "星期六"
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationOAuthTab.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/SaveButton.tsx
|
||||
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableActionButtons.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
#: src/modules/command-menu-item/record/constants/DashboardCommandMenuItemsConfig.tsx
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
@@ -11597,11 +11594,6 @@ msgstr "另存為新視圖"
|
||||
msgid "Save Dashboard"
|
||||
msgstr "保存儀表板"
|
||||
|
||||
#. js-lingui-id: BZVCCj
|
||||
#: src/modules/command-menu-item/record/constants/DefaultRecordCommandMenuItemsConfig.tsx
|
||||
msgid "Save Page Layout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
@@ -12640,6 +12632,11 @@ msgstr "一些"
|
||||
msgid "Some folders"
|
||||
msgstr "某些資料夾"
|
||||
|
||||
#. js-lingui-id: hqUWge
|
||||
#: src/modules/layout-customization/hooks/useSaveLayoutCustomization.ts
|
||||
msgid "Some layout changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nwtY4N
|
||||
#: src/pages/auth/Authorize.tsx
|
||||
msgid "Something went wrong"
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
import { useExecuteTasksOnAnyLocationChange } from '@/app/hooks/useExecuteTasksOnAnyLocationChange';
|
||||
import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState';
|
||||
import { isDashboardInEditModeComponentState } from '@/page-layout/states/isDashboardInEditModeComponentState';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { createStore, Provider as JotaiProvider } from 'jotai';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
const mockCloseAnyOpenDropdown = jest.fn();
|
||||
|
||||
jest.mock('@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown', () => ({
|
||||
useCloseAnyOpenDropdown: () => ({
|
||||
closeAnyOpenDropdown: mockCloseAnyOpenDropdown,
|
||||
}),
|
||||
}));
|
||||
|
||||
const PAGE_LAYOUT_ID = 'test-page-layout-id';
|
||||
|
||||
const getWrapper =
|
||||
(store = createStore()) =>
|
||||
({ children }: { children: ReactNode }) => (
|
||||
<JotaiProvider store={store}>{children}</JotaiProvider>
|
||||
);
|
||||
|
||||
describe('useExecuteTasksOnAnyLocationChange', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should reset page layout edit state when layout customization is inactive', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(currentPageLayoutIdState.atom, PAGE_LAYOUT_ID);
|
||||
store.set(
|
||||
isDashboardInEditModeComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, false);
|
||||
|
||||
const { result } = renderHook(() => useExecuteTasksOnAnyLocationChange(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
act(() => {
|
||||
result.current.executeTasksOnAnyLocationChange();
|
||||
});
|
||||
|
||||
expect(mockCloseAnyOpenDropdown).toHaveBeenCalledTimes(1);
|
||||
expect(store.get(currentPageLayoutIdState.atom)).toBeNull();
|
||||
expect(
|
||||
store.get(
|
||||
isDashboardInEditModeComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID,
|
||||
}),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should not reset page layout edit state when layout customization is active', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(currentPageLayoutIdState.atom, PAGE_LAYOUT_ID);
|
||||
store.set(
|
||||
isDashboardInEditModeComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
|
||||
const { result } = renderHook(() => useExecuteTasksOnAnyLocationChange(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
act(() => {
|
||||
result.current.executeTasksOnAnyLocationChange();
|
||||
});
|
||||
|
||||
expect(mockCloseAnyOpenDropdown).toHaveBeenCalledTimes(1);
|
||||
expect(store.get(currentPageLayoutIdState.atom)).toBe(PAGE_LAYOUT_ID);
|
||||
expect(
|
||||
store.get(
|
||||
isDashboardInEditModeComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState';
|
||||
@@ -8,7 +9,7 @@ import { fieldsWidgetGroupsPersistedComponentState } from '@/page-layout/states/
|
||||
import { fieldsWidgetUngroupedFieldsDraftComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsDraftComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsPersistedComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsPersistedComponentState';
|
||||
import { hasInitializedFieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/hasInitializedFieldsWidgetGroupsDraftComponentState';
|
||||
import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState';
|
||||
import { isDashboardInEditModeComponentState } from '@/page-layout/states/isDashboardInEditModeComponentState';
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutIsInitializedComponentState } from '@/page-layout/states/pageLayoutIsInitializedComponentState';
|
||||
@@ -57,7 +58,7 @@ export const useExecuteTasksOnAnyLocationChange = () => {
|
||||
}
|
||||
|
||||
store.set(
|
||||
isPageLayoutInEditModeComponentState.atomFamily({
|
||||
isDashboardInEditModeComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
false,
|
||||
@@ -137,7 +138,14 @@ export const useExecuteTasksOnAnyLocationChange = () => {
|
||||
*/
|
||||
const executeTasksOnAnyLocationChange = () => {
|
||||
closeAnyOpenDropdown();
|
||||
resetPageLayoutEditMode();
|
||||
|
||||
const isLayoutCustomizationModeEnabled = store.get(
|
||||
isLayoutCustomizationModeEnabledState.atom,
|
||||
);
|
||||
|
||||
if (!isLayoutCustomizationModeEnabled) {
|
||||
resetPageLayoutEditMode();
|
||||
}
|
||||
};
|
||||
|
||||
return { executeTasksOnAnyLocationChange };
|
||||
|
||||
-8
@@ -24,9 +24,7 @@ import { CancelDashboardSingleRecordCommand } from '@/command-menu-item/record/s
|
||||
import { DuplicateDashboardSingleRecordCommand } from '@/command-menu-item/record/single-record/dashboard/components/DuplicateDashboardSingleRecordCommand';
|
||||
import { EditDashboardSingleRecordCommand } from '@/command-menu-item/record/single-record/dashboard/components/EditDashboardSingleRecordCommand';
|
||||
import { SaveDashboardSingleRecordCommand } from '@/command-menu-item/record/single-record/dashboard/components/SaveDashboardSingleRecordCommand';
|
||||
import { CancelRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/CancelRecordPageLayoutSingleRecordCommand';
|
||||
import { EditRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/EditRecordPageLayoutSingleRecordCommand';
|
||||
import { SaveRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/SaveRecordPageLayoutSingleRecordCommand';
|
||||
import { SeeVersionWorkflowRunSingleRecordCommand } from '@/command-menu-item/record/single-record/workflow-runs/components/SeeVersionWorkflowRunSingleRecordCommand';
|
||||
import { SeeWorkflowWorkflowRunSingleRecordCommand } from '@/command-menu-item/record/single-record/workflow-runs/components/SeeWorkflowWorkflowRunSingleRecordCommand';
|
||||
import { StopWorkflowRunSingleRecordCommand } from '@/command-menu-item/record/single-record/workflow-runs/components/StopWorkflowRunSingleRecordCommand';
|
||||
@@ -96,9 +94,6 @@ export const ENGINE_COMPONENT_KEY_COMPONENT_MAP: Record<
|
||||
[EngineComponentKey.USE_AS_DRAFT_WORKFLOW_VERSION]: (
|
||||
<UseAsDraftWorkflowVersionSingleRecordCommand />
|
||||
),
|
||||
[EngineComponentKey.SAVE_RECORD_PAGE_LAYOUT]: (
|
||||
<SaveRecordPageLayoutSingleRecordCommand />
|
||||
),
|
||||
[EngineComponentKey.SAVE_DASHBOARD_LAYOUT]: (
|
||||
<SaveDashboardSingleRecordCommand />
|
||||
),
|
||||
@@ -136,9 +131,6 @@ export const ENGINE_COMPONENT_KEY_COMPONENT_MAP: Record<
|
||||
[EngineComponentKey.EDIT_RECORD_PAGE_LAYOUT]: (
|
||||
<EditRecordPageLayoutSingleRecordCommand />
|
||||
),
|
||||
[EngineComponentKey.CANCEL_RECORD_PAGE_LAYOUT]: (
|
||||
<CancelRecordPageLayoutSingleRecordCommand />
|
||||
),
|
||||
[EngineComponentKey.EDIT_DASHBOARD_LAYOUT]: (
|
||||
<EditDashboardSingleRecordCommand />
|
||||
),
|
||||
|
||||
+7
@@ -13,14 +13,20 @@ export const CommandDropdownItem = ({
|
||||
action,
|
||||
onClick,
|
||||
to,
|
||||
disabled = false,
|
||||
}: {
|
||||
action: CommandMenuItemDisplayProps;
|
||||
onClick?: () => void;
|
||||
to?: string;
|
||||
disabled?: boolean;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleClick = () => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
onClick?.();
|
||||
if (isDefined(to)) {
|
||||
navigate(to);
|
||||
@@ -45,6 +51,7 @@ export const CommandDropdownItem = ({
|
||||
LeftIcon={action.Icon}
|
||||
onClick={handleClick}
|
||||
text={getCommandMenuItemLabel(action.label)}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
);
|
||||
|
||||
+3
-1
@@ -11,11 +11,13 @@ export const CommandListItem = ({
|
||||
onClick,
|
||||
to,
|
||||
disabled = false,
|
||||
showDisabledLoader = false,
|
||||
}: {
|
||||
action: CommandMenuItemDisplayProps;
|
||||
onClick?: () => void;
|
||||
to?: string;
|
||||
disabled?: boolean;
|
||||
showDisabledLoader?: boolean;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -41,7 +43,7 @@ export const CommandListItem = ({
|
||||
onClick={disabled ? undefined : onClick}
|
||||
hotKeys={action.hotKeys}
|
||||
disabled={disabled}
|
||||
RightComponent={disabled ? <Loader /> : undefined}
|
||||
RightComponent={disabled && showDisabledLoader ? <Loader /> : undefined}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
);
|
||||
|
||||
+10
-1
@@ -5,10 +5,19 @@ export const CommandMenuItemButton = ({
|
||||
action,
|
||||
onClick,
|
||||
to,
|
||||
disabled = false,
|
||||
}: {
|
||||
action: CommandMenuItemDisplayProps;
|
||||
onClick?: (event?: React.MouseEvent<HTMLElement>) => void;
|
||||
to?: string;
|
||||
disabled?: boolean;
|
||||
}) => {
|
||||
return <CommandMenuButton command={action} to={to} onClick={onClick} />;
|
||||
return (
|
||||
<CommandMenuButton
|
||||
command={action}
|
||||
to={to}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+34
-7
@@ -3,8 +3,10 @@ import { CommandDropdownItem } from '@/command-menu-item/display/components/Comm
|
||||
import { CommandListItem } from '@/command-menu-item/display/components/CommandListItem';
|
||||
import { CommandConfigContext } from '@/command-menu-item/contexts/CommandConfigContext';
|
||||
import { CommandMenuContext } from '@/command-menu-item/contexts/CommandMenuContext';
|
||||
import { useIsCommandBlockedByGlobalLayoutCustomization } from '@/command-menu-item/hooks/useIsCommandBlockedByGlobalLayoutCustomization';
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import { useContext } from 'react';
|
||||
import { type Nullable } from 'twenty-shared/types';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { type MenuItemAccent } from 'twenty-ui/navigation';
|
||||
@@ -12,47 +14,72 @@ import { type MenuItemAccent } from 'twenty-ui/navigation';
|
||||
export type CommandMenuItemDisplayProps = {
|
||||
key: string;
|
||||
label: MessageDescriptor | string;
|
||||
shortLabel?: MessageDescriptor | string;
|
||||
shortLabel?: Nullable<MessageDescriptor | string>;
|
||||
description?: MessageDescriptor | string;
|
||||
Icon: IconComponent;
|
||||
isPrimaryCTA?: boolean;
|
||||
accent?: MenuItemAccent;
|
||||
hotKeys?: string[];
|
||||
hotKeys?: Nullable<string[]>;
|
||||
};
|
||||
|
||||
export const CommandMenuItemDisplay = ({
|
||||
onClick,
|
||||
to,
|
||||
disabled,
|
||||
showDisabledLoader = false,
|
||||
}: {
|
||||
onClick?: (event?: React.MouseEvent<HTMLElement>) => void;
|
||||
to?: string;
|
||||
disabled?: boolean;
|
||||
showDisabledLoader?: boolean;
|
||||
}) => {
|
||||
const action = useContext(CommandConfigContext);
|
||||
const { displayType } = useContext(CommandMenuContext);
|
||||
const isBlockedByGlobalLayoutCustomization =
|
||||
useIsCommandBlockedByGlobalLayoutCustomization(action);
|
||||
|
||||
if (!action) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isDisabled =
|
||||
disabled === true || isBlockedByGlobalLayoutCustomization === true;
|
||||
|
||||
const onClickWhenEnabled = isDisabled ? undefined : onClick;
|
||||
const toWhenEnabled = isDisabled ? undefined : to;
|
||||
|
||||
if (displayType === 'button') {
|
||||
return <CommandMenuItemButton action={action} onClick={onClick} to={to} />;
|
||||
return (
|
||||
<CommandMenuItemButton
|
||||
action={action}
|
||||
onClick={onClickWhenEnabled}
|
||||
to={toWhenEnabled}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (displayType === 'listItem') {
|
||||
return (
|
||||
<CommandListItem
|
||||
action={action}
|
||||
onClick={onClick}
|
||||
to={to}
|
||||
disabled={disabled}
|
||||
onClick={onClickWhenEnabled}
|
||||
to={toWhenEnabled}
|
||||
disabled={isDisabled}
|
||||
showDisabledLoader={showDisabledLoader}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (displayType === 'dropdownItem') {
|
||||
return <CommandDropdownItem action={action} onClick={onClick} to={to} />;
|
||||
return (
|
||||
<CommandDropdownItem
|
||||
action={action}
|
||||
onClick={onClickWhenEnabled}
|
||||
to={toWhenEnabled}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return assertUnreachable(displayType, 'Unsupported display type');
|
||||
|
||||
+7
-1
@@ -38,5 +38,11 @@ export const HeadlessFrontComponentCommandMenuItem = ({
|
||||
onClick();
|
||||
};
|
||||
|
||||
return <CommandMenuItemDisplay onClick={handleClick} disabled={isMounted} />;
|
||||
return (
|
||||
<CommandMenuItemDisplay
|
||||
onClick={handleClick}
|
||||
disabled={isMounted}
|
||||
showDisabledLoader={isMounted}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ export const COMMAND_MENU_ITEM_FRAGMENT = gql`
|
||||
shortLabel
|
||||
position
|
||||
isPinned
|
||||
hotKeys
|
||||
conditionalAvailabilityExpression
|
||||
availabilityType
|
||||
availabilityObjectMetadataId
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { useIsCommandBlockedByGlobalLayoutCustomization } from '@/command-menu-item/hooks/useIsCommandBlockedByGlobalLayoutCustomization';
|
||||
import { type CommandMenuItemConfig } from '@/command-menu-item/types/CommandMenuItemConfig';
|
||||
import { CommandMenuItemScope } from '@/command-menu-item/types/CommandMenuItemScope';
|
||||
import { CommandMenuItemType } from '@/command-menu-item/types/CommandMenuItemType';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { createStore, Provider as JotaiProvider } from 'jotai';
|
||||
import { type ReactNode } from 'react';
|
||||
import { CommandMenuItemViewType } from 'twenty-shared/types';
|
||||
import { Icon123 } from 'twenty-ui/display';
|
||||
|
||||
const getWrapper =
|
||||
(store = createStore()) =>
|
||||
({ children }: { children: ReactNode }) => (
|
||||
<JotaiProvider store={store}>{children}</JotaiProvider>
|
||||
);
|
||||
|
||||
const buildCommandMenuItemConfig = (
|
||||
isAllowedDuringGlobalLayoutCustomization?: boolean,
|
||||
): CommandMenuItemConfig => ({
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.Global,
|
||||
key: 'test-command',
|
||||
label: 'Test Command',
|
||||
position: 1,
|
||||
Icon: Icon123,
|
||||
availableOn: [CommandMenuItemViewType.GLOBAL],
|
||||
shouldBeRegistered: () => true,
|
||||
component: null,
|
||||
isAllowedDuringGlobalLayoutCustomization,
|
||||
});
|
||||
|
||||
describe('useIsCommandBlockedByGlobalLayoutCustomization', () => {
|
||||
it('should not block commands when global layout customization is inactive', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
const commandMenuItemConfig = buildCommandMenuItemConfig(false);
|
||||
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, false);
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useIsCommandBlockedByGlobalLayoutCustomization(commandMenuItemConfig),
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should block commands by default when global layout customization is active', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
const commandMenuItemConfig = buildCommandMenuItemConfig();
|
||||
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useIsCommandBlockedByGlobalLayoutCustomization(commandMenuItemConfig),
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow commands explicitly marked for global layout customization', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
const commandMenuItemConfig = buildCommandMenuItemConfig(true);
|
||||
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useIsCommandBlockedByGlobalLayoutCustomization(commandMenuItemConfig),
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
});
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
import { useRegisteredCommandMenuItems } from '@/command-menu-item/hooks/useRegisteredCommandMenuItems';
|
||||
import { CommandMenuItemScope } from '@/command-menu-item/types/CommandMenuItemScope';
|
||||
import { CommandMenuItemType } from '@/command-menu-item/types/CommandMenuItemType';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { createStore, Provider as JotaiProvider } from 'jotai';
|
||||
import { type ReactNode } from 'react';
|
||||
import { CommandMenuItemViewType } from 'twenty-shared/types';
|
||||
import { Icon123 } from 'twenty-ui/display';
|
||||
|
||||
jest.mock('@/command-menu-item/utils/getCommandMenuItemConfig', () => ({
|
||||
getCommandMenuItemConfig: () => ({}),
|
||||
}));
|
||||
|
||||
jest.mock(
|
||||
'@/command-menu-item/record-agnostic/hooks/useRelatedRecordCommands',
|
||||
() => ({
|
||||
useRelatedRecordCommands: () => ({}),
|
||||
}),
|
||||
);
|
||||
|
||||
jest.mock('@/settings/roles/hooks/usePermissionFlagMap', () => ({
|
||||
usePermissionFlagMap: () => ({}),
|
||||
}));
|
||||
|
||||
jest.mock(
|
||||
'@/command-menu-item/record-agnostic/hooks/useRecordAgnosticCommands',
|
||||
() => ({
|
||||
useRecordAgnosticCommands: () => ({
|
||||
pageEditItem: {
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.Global,
|
||||
key: 'page-edit-item',
|
||||
label: 'Page Edit Item',
|
||||
position: 0,
|
||||
Icon: Icon123,
|
||||
availableOn: [CommandMenuItemViewType.PAGE_EDIT_MODE],
|
||||
shouldBeRegistered: () => true,
|
||||
component: null,
|
||||
},
|
||||
showItem: {
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.Global,
|
||||
key: 'show-item',
|
||||
label: 'Show Item',
|
||||
position: 1,
|
||||
Icon: Icon123,
|
||||
availableOn: [CommandMenuItemViewType.SHOW_PAGE],
|
||||
shouldBeRegistered: () => true,
|
||||
component: null,
|
||||
},
|
||||
globalItem: {
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.Global,
|
||||
key: 'global-item',
|
||||
label: 'Global Item',
|
||||
position: 2,
|
||||
Icon: Icon123,
|
||||
availableOn: [CommandMenuItemViewType.GLOBAL],
|
||||
shouldBeRegistered: () => true,
|
||||
component: null,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
const CONTEXT_STORE_INSTANCE_ID = 'test-context-store-instance-id';
|
||||
|
||||
const getWrapper = (store = createStore()) => {
|
||||
return ({ children }: { children: ReactNode }) => (
|
||||
<JotaiProvider store={store}>
|
||||
<ContextStoreComponentInstanceContext.Provider
|
||||
value={{ instanceId: CONTEXT_STORE_INSTANCE_ID }}
|
||||
>
|
||||
{children}
|
||||
</ContextStoreComponentInstanceContext.Provider>
|
||||
</JotaiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const shouldBeRegisteredParams = {
|
||||
objectPermissions: {
|
||||
canReadObjectRecords: true,
|
||||
canUpdateObjectRecords: true,
|
||||
canSoftDeleteObjectRecords: true,
|
||||
canDestroyObjectRecords: true,
|
||||
restrictedFields: {},
|
||||
objectMetadataId: '',
|
||||
rowLevelPermissionPredicates: [],
|
||||
rowLevelPermissionPredicateGroups: [],
|
||||
},
|
||||
getTargetObjectReadPermission: () => true,
|
||||
getTargetObjectWritePermission: () => true,
|
||||
isFeatureFlagEnabled: () => true,
|
||||
};
|
||||
|
||||
describe('useRegisteredCommandMenuItems', () => {
|
||||
it('should register SHOW_PAGE and GLOBAL commands when page is not in edit mode', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
ContextStoreViewType.ShowPage,
|
||||
);
|
||||
store.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
{ mode: 'selection', selectedRecordIds: [] },
|
||||
);
|
||||
|
||||
act(() => {
|
||||
store.set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRegisteredCommandMenuItems(
|
||||
shouldBeRegisteredParams as Parameters<
|
||||
typeof useRegisteredCommandMenuItems
|
||||
>[0],
|
||||
),
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.map((item) => item.key)).toEqual([
|
||||
'show-item',
|
||||
'global-item',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should register PAGE_EDIT_MODE commands when page is in edit mode', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
ContextStoreViewType.ShowPage,
|
||||
);
|
||||
store.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
{ mode: 'selection', selectedRecordIds: [] },
|
||||
);
|
||||
|
||||
act(() => {
|
||||
store.set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRegisteredCommandMenuItems(
|
||||
shouldBeRegisteredParams as Parameters<
|
||||
typeof useRegisteredCommandMenuItems
|
||||
>[0],
|
||||
),
|
||||
{
|
||||
wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.map((item) => item.key)).toEqual(['page-edit-item']);
|
||||
});
|
||||
});
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { type CommandMenuItemConfig } from '@/command-menu-item/types/CommandMenuItemConfig';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
|
||||
export const useIsCommandBlockedByGlobalLayoutCustomization = (
|
||||
commandMenuItemConfig: CommandMenuItemConfig | null,
|
||||
) => {
|
||||
const isLayoutCustomizationModeEnabled = useAtomStateValue(
|
||||
isLayoutCustomizationModeEnabledState,
|
||||
);
|
||||
|
||||
if (!isLayoutCustomizationModeEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !commandMenuItemConfig?.isAllowedDuringGlobalLayoutCustomization;
|
||||
};
|
||||
-59
@@ -21,9 +21,7 @@ import { NavigateToNextRecordSingleRecordCommand } from '@/command-menu-item/rec
|
||||
import { NavigateToPreviousRecordSingleRecordCommand } from '@/command-menu-item/record/single-record/components/NavigateToPreviousRecordSingleRecordCommand';
|
||||
import { RemoveFromFavoritesSingleRecordCommand } from '@/command-menu-item/record/single-record/components/RemoveFromFavoritesSingleRecordCommand';
|
||||
import { RestoreSingleRecordCommand } from '@/command-menu-item/record/single-record/components/RestoreSingleRecordCommand';
|
||||
import { CancelRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/CancelRecordPageLayoutSingleRecordCommand';
|
||||
import { EditRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/EditRecordPageLayoutSingleRecordCommand';
|
||||
import { SaveRecordPageLayoutSingleRecordCommand } from '@/command-menu-item/record/single-record/record-page-layout/components/SaveRecordPageLayoutSingleRecordCommand';
|
||||
import { RecordPageLayoutSingleRecordCommandKeys } from '@/command-menu-item/record/single-record/record-page-layout/types/RecordPageLayoutSingleRecordCommandKeys';
|
||||
import { SingleRecordCommandKeys } from '@/command-menu-item/record/single-record/types/SingleRecordCommandKeys';
|
||||
import { type CommandMenuItemConfig } from '@/command-menu-item/types/CommandMenuItemConfig';
|
||||
@@ -45,11 +43,9 @@ import {
|
||||
import {
|
||||
IconArrowMerge,
|
||||
IconBuildingSkyscraper,
|
||||
IconCancel,
|
||||
IconCheckbox,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconDeviceFloppy,
|
||||
IconEdit,
|
||||
IconEyeOff,
|
||||
IconFileExport,
|
||||
@@ -814,59 +810,4 @@ export const DEFAULT_RECORD_COMMAND_MENU_ITEMS_CONFIG: Record<
|
||||
availableOn: [CommandMenuItemViewType.SHOW_PAGE],
|
||||
component: <EditRecordPageLayoutSingleRecordCommand />,
|
||||
},
|
||||
[RecordPageLayoutSingleRecordCommandKeys.SAVE_RECORD_PAGE_LAYOUT]: {
|
||||
key: RecordPageLayoutSingleRecordCommandKeys.SAVE_RECORD_PAGE_LAYOUT,
|
||||
label: msg`Save Page Layout`,
|
||||
shortLabel: msg`Save`,
|
||||
isPinned: true,
|
||||
isPrimaryCTA: true,
|
||||
position: 31,
|
||||
Icon: IconDeviceFloppy,
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.RecordSelection,
|
||||
requiredPermissionFlag: PermissionFlagType.LAYOUTS,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
objectPermissions,
|
||||
objectMetadataItem,
|
||||
isFeatureFlagEnabled,
|
||||
}) =>
|
||||
isFeatureFlagEnabled(
|
||||
FeatureFlagKey.IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED,
|
||||
) &&
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
objectPermissions.canUpdateObjectRecords &&
|
||||
objectMetadataItem?.nameSingular !== CoreObjectNameSingular.Dashboard,
|
||||
availableOn: [CommandMenuItemViewType.PAGE_EDIT_MODE],
|
||||
component: <SaveRecordPageLayoutSingleRecordCommand />,
|
||||
},
|
||||
[RecordPageLayoutSingleRecordCommandKeys.CANCEL_RECORD_PAGE_LAYOUT_EDITION]: {
|
||||
key: RecordPageLayoutSingleRecordCommandKeys.CANCEL_RECORD_PAGE_LAYOUT_EDITION,
|
||||
label: msg`Cancel Edition`,
|
||||
shortLabel: msg`Cancel`,
|
||||
isPinned: true,
|
||||
position: 32,
|
||||
Icon: IconCancel,
|
||||
type: CommandMenuItemType.Standard,
|
||||
scope: CommandMenuItemScope.RecordSelection,
|
||||
requiredPermissionFlag: PermissionFlagType.LAYOUTS,
|
||||
shouldBeRegistered: ({
|
||||
selectedRecord,
|
||||
objectPermissions,
|
||||
objectMetadataItem,
|
||||
isFeatureFlagEnabled,
|
||||
}) =>
|
||||
isFeatureFlagEnabled(
|
||||
FeatureFlagKey.IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED,
|
||||
) &&
|
||||
isDefined(selectedRecord) &&
|
||||
!selectedRecord?.isRemote &&
|
||||
!isDefined(selectedRecord?.deletedAt) &&
|
||||
objectPermissions.canUpdateObjectRecords &&
|
||||
objectMetadataItem?.nameSingular !== CoreObjectNameSingular.Dashboard,
|
||||
availableOn: [CommandMenuItemViewType.PAGE_EDIT_MODE],
|
||||
component: <CancelRecordPageLayoutSingleRecordCommand />,
|
||||
},
|
||||
};
|
||||
|
||||
+3
-6
@@ -1,15 +1,12 @@
|
||||
import { useEnterLayoutCustomizationMode } from '@/layout-customization/hooks/useEnterLayoutCustomizationMode';
|
||||
import { Command } from '@/command-menu-item/display/components/Command';
|
||||
import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/common/states/isNavigationMenuInEditModeState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
|
||||
export const EditNavigationSidebarNoSelectionRecordCommand = () => {
|
||||
const setIsNavigationMenuInEditMode = useSetAtomState(
|
||||
isNavigationMenuInEditModeState,
|
||||
);
|
||||
const { enterLayoutCustomizationMode } = useEnterLayoutCustomizationMode();
|
||||
|
||||
return (
|
||||
<Command
|
||||
onClick={() => setIsNavigationMenuInEditMode(true)}
|
||||
onClick={() => enterLayoutCustomizationMode()}
|
||||
closeSidePanelOnCommandMenuListExecution
|
||||
/>
|
||||
);
|
||||
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
import { Command } from '@/command-menu-item/display/components/Command';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useRecordPageLayoutIdFromRecordStoreOrThrow } from '@/page-layout/hooks/useRecordPageLayoutIdFromRecordStoreOrThrow';
|
||||
import { useResetDraftPageLayoutToPersistedPageLayout } from '@/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
|
||||
export const CancelRecordPageLayoutSingleRecordCommand = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
|
||||
const { pageLayoutId } = useRecordPageLayoutIdFromRecordStoreOrThrow({
|
||||
targetObjectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const { resetDraftPageLayoutToPersistedPageLayout } =
|
||||
useResetDraftPageLayoutToPersistedPageLayout(pageLayoutId);
|
||||
|
||||
const handleClick = () => {
|
||||
closeSidePanelMenu();
|
||||
|
||||
resetDraftPageLayoutToPersistedPageLayout();
|
||||
setIsPageLayoutInEditMode(false);
|
||||
};
|
||||
|
||||
return <Command onClick={handleClick} />;
|
||||
};
|
||||
+3
-12
@@ -1,23 +1,14 @@
|
||||
import { useEnterLayoutCustomizationMode } from '@/layout-customization/hooks/useEnterLayoutCustomizationMode';
|
||||
import { Command } from '@/command-menu-item/display/components/Command';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useRecordPageLayoutIdFromRecordStoreOrThrow } from '@/page-layout/hooks/useRecordPageLayoutIdFromRecordStoreOrThrow';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { useResetLocationHash } from 'twenty-ui/utilities';
|
||||
|
||||
export const EditRecordPageLayoutSingleRecordCommand = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
|
||||
const { pageLayoutId } = useRecordPageLayoutIdFromRecordStoreOrThrow({
|
||||
targetObjectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
const { enterLayoutCustomizationMode } = useEnterLayoutCustomizationMode();
|
||||
|
||||
const { resetLocationHash } = useResetLocationHash();
|
||||
|
||||
const handleClick = () => {
|
||||
setIsPageLayoutInEditMode(true);
|
||||
enterLayoutCustomizationMode();
|
||||
resetLocationHash();
|
||||
};
|
||||
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
import { Command } from '@/command-menu-item/display/components/Command';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
|
||||
import { useRecordPageLayoutIdFromRecordStoreOrThrow } from '@/page-layout/hooks/useRecordPageLayoutIdFromRecordStoreOrThrow';
|
||||
import { useSaveFieldsWidgetGroups } from '@/page-layout/hooks/useSaveFieldsWidgetGroups';
|
||||
import { useSavePageLayout } from '@/page-layout/hooks/useSavePageLayout';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
|
||||
export const SaveRecordPageLayoutSingleRecordCommand = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
|
||||
const { pageLayoutId } = useRecordPageLayoutIdFromRecordStoreOrThrow({
|
||||
targetObjectNameSingular: objectMetadataItem.nameSingular,
|
||||
});
|
||||
|
||||
const { savePageLayout } = useSavePageLayout(pageLayoutId);
|
||||
const { saveFieldsWidgetGroups } = useSaveFieldsWidgetGroups({
|
||||
pageLayoutId,
|
||||
});
|
||||
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const handleClick = async () => {
|
||||
const result = await savePageLayout();
|
||||
|
||||
if (result.status === 'successful') {
|
||||
await saveFieldsWidgetGroups();
|
||||
|
||||
closeSidePanelMenu();
|
||||
setIsPageLayoutInEditMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
return <Command onClick={handleClick} />;
|
||||
};
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
export enum RecordPageLayoutSingleRecordCommandKeys {
|
||||
EDIT_RECORD_PAGE_LAYOUT = 'edit-record-page-layout-single-record',
|
||||
SAVE_RECORD_PAGE_LAYOUT = 'save-record-page-layout-single-record',
|
||||
CANCEL_RECORD_PAGE_LAYOUT_EDITION = 'cancel-record-page-layout-edition-single-record',
|
||||
}
|
||||
|
||||
+4
-2
@@ -100,10 +100,11 @@ const buildCommandMenuItemFromFrontComponent = ({
|
||||
key: `command-menu-item-front-component-${item.id}`,
|
||||
scope,
|
||||
label: displayLabel,
|
||||
shortLabel: item.shortLabel ?? undefined,
|
||||
shortLabel: item.shortLabel,
|
||||
position: item.position,
|
||||
isPinned,
|
||||
Icon,
|
||||
hotKeys: item.hotKeys,
|
||||
shouldBeRegistered: () =>
|
||||
evaluateConditionalAvailabilityExpression(
|
||||
item.conditionalAvailabilityExpression,
|
||||
@@ -148,10 +149,11 @@ const buildCommandItemFromEngineKey = ({
|
||||
key: `command-menu-item-engine-${item.id}`,
|
||||
scope,
|
||||
label: item.label,
|
||||
shortLabel: item.shortLabel ?? undefined,
|
||||
shortLabel: item.shortLabel,
|
||||
position: item.position,
|
||||
isPinned,
|
||||
Icon,
|
||||
hotKeys: item.hotKeys,
|
||||
shouldBeRegistered: () =>
|
||||
evaluateConditionalAvailabilityExpression(
|
||||
item.conditionalAvailabilityExpression,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { type CommandMenuItemScope } from '@/command-menu-item/types/CommandMenuItemScope';
|
||||
import { type CommandMenuItemType } from '@/command-menu-item/types/CommandMenuItemType';
|
||||
import { type CommandMenuItemViewType } from 'twenty-shared/types';
|
||||
import { type ShouldBeRegisteredFunctionParams } from '@/command-menu-item/types/ShouldBeRegisteredFunctionParams';
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import {
|
||||
type CommandMenuItemViewType,
|
||||
type Nullable,
|
||||
} from 'twenty-shared/types';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { type MenuItemAccent } from 'twenty-ui/navigation';
|
||||
import { type PermissionFlagType } from '~/generated-metadata/graphql';
|
||||
@@ -12,7 +15,7 @@ export type CommandMenuItemConfig = {
|
||||
scope: CommandMenuItemScope;
|
||||
key: string;
|
||||
label: MessageDescriptor | string;
|
||||
shortLabel?: MessageDescriptor | string;
|
||||
shortLabel?: Nullable<MessageDescriptor | string>;
|
||||
description?: MessageDescriptor | string;
|
||||
position: number;
|
||||
Icon: IconComponent;
|
||||
@@ -22,6 +25,7 @@ export type CommandMenuItemConfig = {
|
||||
availableOn?: CommandMenuItemViewType[];
|
||||
shouldBeRegistered: (params: ShouldBeRegisteredFunctionParams) => boolean;
|
||||
component: React.ReactNode;
|
||||
hotKeys?: string[];
|
||||
hotKeys?: Nullable<string[]>;
|
||||
requiredPermissionFlag?: PermissionFlagType;
|
||||
isAllowedDuringGlobalLayoutCustomization?: boolean;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@ import { styled } from '@linaria/react';
|
||||
import { i18n, type MessageDescriptor } from '@lingui/core';
|
||||
import { isString } from '@sniptt/guards';
|
||||
import { type MouseEvent } from 'react';
|
||||
import { type Nullable } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
AppTooltip,
|
||||
type IconComponent,
|
||||
@@ -19,12 +21,13 @@ export type CommandMenuButtonProps = {
|
||||
command: {
|
||||
key: string;
|
||||
label: string | MessageDescriptor;
|
||||
shortLabel?: string | MessageDescriptor;
|
||||
shortLabel?: Nullable<string | MessageDescriptor>;
|
||||
Icon: IconComponent;
|
||||
isPrimaryCTA?: boolean;
|
||||
};
|
||||
onClick?: (event?: MouseEvent<HTMLElement>) => void;
|
||||
to?: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const getCommandMenuButtonLabel = (
|
||||
@@ -37,13 +40,13 @@ export const CommandMenuButton = ({
|
||||
command,
|
||||
onClick,
|
||||
to,
|
||||
disabled = false,
|
||||
}: CommandMenuButtonProps) => {
|
||||
const resolvedLabel = getCommandMenuButtonLabel(command.label);
|
||||
|
||||
const resolvedShortLabel =
|
||||
command.shortLabel === undefined
|
||||
? undefined
|
||||
: getCommandMenuButtonLabel(command.shortLabel);
|
||||
const resolvedShortLabel = isDefined(command.shortLabel)
|
||||
? getCommandMenuButtonLabel(command.shortLabel)
|
||||
: undefined;
|
||||
|
||||
const buttonAccent = command.isPrimaryCTA ? 'blue' : 'default';
|
||||
|
||||
@@ -57,6 +60,7 @@ export const CommandMenuButton = ({
|
||||
accent={buttonAccent}
|
||||
to={to}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
title={resolvedShortLabel}
|
||||
ariaLabel={resolvedLabel}
|
||||
/>
|
||||
@@ -69,6 +73,7 @@ export const CommandMenuButton = ({
|
||||
accent={buttonAccent}
|
||||
to={to}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
ariaLabel={resolvedLabel}
|
||||
/>
|
||||
<StyledWrapper>
|
||||
|
||||
@@ -4,9 +4,10 @@ import { IconArrowUpRight, type IconComponent } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
import { useCommandMenuOnItemClick } from '@/command-menu/hooks/useCommandMenuOnItemClick';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
|
||||
import { type Nullable } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export type CommandMenuItemProps = {
|
||||
label: string;
|
||||
@@ -15,7 +16,7 @@ export type CommandMenuItemProps = {
|
||||
id: string;
|
||||
onClick?: () => void;
|
||||
Icon?: IconComponent;
|
||||
hotKeys?: string[];
|
||||
hotKeys?: Nullable<string[]>;
|
||||
LeftComponent?: ReactNode;
|
||||
RightComponent?: ReactNode;
|
||||
contextualTextPosition?: 'left' | 'right';
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import { useCancelLayoutCustomization } from '@/layout-customization/hooks/useCancelLayoutCustomization';
|
||||
import { useIsLayoutCustomizationDirty } from '@/layout-customization/hooks/useIsLayoutCustomizationDirty';
|
||||
import { useSaveLayoutCustomization } from '@/layout-customization/hooks/useSaveLayoutCustomization';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { useContext } from 'react';
|
||||
import { IconCheck, IconPaint } from 'twenty-ui/display';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
background: ${themeCssVariables.color.blue};
|
||||
box-sizing: border-box;
|
||||
color: ${themeCssVariables.font.color.inverted};
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[3]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledTitle = styled.span`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const LayoutCustomizationBarContent = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { t } = useLingui();
|
||||
|
||||
const { save, isSaving } = useSaveLayoutCustomization();
|
||||
const { cancel } = useCancelLayoutCustomization();
|
||||
const { isDirty } = useIsLayoutCustomizationDirty();
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration.normal,
|
||||
ease: 'easeInOut',
|
||||
}}
|
||||
>
|
||||
<StyledContainer>
|
||||
<StyledTitle>
|
||||
<IconPaint size={theme.icon.size.md} />
|
||||
{t`Layout customization`}
|
||||
</StyledTitle>
|
||||
<SaveAndCancelButtons
|
||||
onSave={save}
|
||||
onCancel={cancel}
|
||||
isSaveDisabled={!isDirty || isSaving}
|
||||
isCancelDisabled={isSaving}
|
||||
isLoading={isSaving}
|
||||
inverted
|
||||
saveIcon={IconCheck}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export const LayoutCustomizationBar = () => {
|
||||
const isLayoutCustomizationModeEnabled = useAtomStateValue(
|
||||
isLayoutCustomizationModeEnabledState,
|
||||
);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isLayoutCustomizationModeEnabled && <LayoutCustomizationBarContent />}
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
import { useIsLayoutCustomizationDirty } from '@/layout-customization/hooks/useIsLayoutCustomizationDirty';
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/common/states/navigationMenuItemsDraftState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { createStore, Provider as JotaiProvider } from 'jotai';
|
||||
import { type ReactNode } from 'react';
|
||||
import {
|
||||
type NavigationMenuItem,
|
||||
NavigationMenuItemType,
|
||||
PageLayoutType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
const PAGE_LAYOUT_ID_1 = 'page-layout-1';
|
||||
const PAGE_LAYOUT_ID_2 = 'page-layout-2';
|
||||
|
||||
const MOCK_PAGE_LAYOUT: PageLayout = {
|
||||
__typename: 'PageLayout',
|
||||
id: PAGE_LAYOUT_ID_1,
|
||||
name: 'Test Layout',
|
||||
type: PageLayoutType.RECORD_PAGE,
|
||||
objectMetadataId: 'obj-1',
|
||||
tabs: [],
|
||||
createdAt: '2024-01-01',
|
||||
updatedAt: '2024-01-01',
|
||||
deletedAt: null,
|
||||
defaultTabToFocusOnMobileAndSidePanelId: null,
|
||||
};
|
||||
|
||||
const MOCK_DRAFT_PAGE_LAYOUT = {
|
||||
id: PAGE_LAYOUT_ID_1,
|
||||
name: 'Test Layout',
|
||||
type: PageLayoutType.RECORD_PAGE,
|
||||
objectMetadataId: 'obj-1',
|
||||
tabs: [] as PageLayout['tabs'],
|
||||
defaultTabToFocusOnMobileAndSidePanelId: null,
|
||||
};
|
||||
|
||||
const getWrapper =
|
||||
(store = createStore()) =>
|
||||
({ children }: { children: ReactNode }) => (
|
||||
<JotaiProvider store={store}>{children}</JotaiProvider>
|
||||
);
|
||||
|
||||
describe('useIsLayoutCustomizationDirty', () => {
|
||||
it('should return not dirty when no layouts are touched and nav is clean', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('navigationMenuItems'), {
|
||||
current: [],
|
||||
draft: [],
|
||||
status: 'up-to-date',
|
||||
});
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, false);
|
||||
|
||||
const { result } = renderHook(() => useIsLayoutCustomizationDirty(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isDirty).toBe(false);
|
||||
});
|
||||
|
||||
it('should return dirty when a touched page layout draft differs from persisted', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('navigationMenuItems'), {
|
||||
current: [],
|
||||
draft: [],
|
||||
status: 'up-to-date',
|
||||
});
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
store.set(activeCustomizationPageLayoutIdsState.atom, [PAGE_LAYOUT_ID_1]);
|
||||
|
||||
store.set(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
MOCK_PAGE_LAYOUT,
|
||||
);
|
||||
store.set(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
{ ...MOCK_DRAFT_PAGE_LAYOUT, name: 'Modified Layout' },
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useIsLayoutCustomizationDirty(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isDirty).toBe(true);
|
||||
});
|
||||
|
||||
it('should return not dirty when all touched layouts match persisted', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('navigationMenuItems'), {
|
||||
current: [],
|
||||
draft: [],
|
||||
status: 'up-to-date',
|
||||
});
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
store.set(activeCustomizationPageLayoutIdsState.atom, [PAGE_LAYOUT_ID_1]);
|
||||
|
||||
store.set(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
MOCK_PAGE_LAYOUT,
|
||||
);
|
||||
store.set(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
MOCK_DRAFT_PAGE_LAYOUT,
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useIsLayoutCustomizationDirty(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isDirty).toBe(false);
|
||||
});
|
||||
|
||||
it('should return dirty when nav is dirty even if page layouts are clean', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
// userWorkspaceId must be null so item passes workspace filter
|
||||
const mockNavItem: NavigationMenuItem = {
|
||||
id: 'nav-1',
|
||||
position: 0,
|
||||
type: NavigationMenuItemType.OBJECT,
|
||||
viewId: null,
|
||||
targetObjectMetadataId: null,
|
||||
folderId: null,
|
||||
name: null,
|
||||
link: null,
|
||||
icon: null,
|
||||
color: null,
|
||||
targetRecordId: null,
|
||||
createdAt: '2024-01-01',
|
||||
updatedAt: '2024-01-01',
|
||||
userWorkspaceId: null,
|
||||
};
|
||||
|
||||
store.set(metadataStoreState.atomFamily('navigationMenuItems'), {
|
||||
current: [mockNavItem],
|
||||
draft: [],
|
||||
status: 'up-to-date',
|
||||
});
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
// Nav draft differs from prefetch
|
||||
store.set(navigationMenuItemsDraftState.atom, []);
|
||||
|
||||
const { result } = renderHook(() => useIsLayoutCustomizationDirty(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isDirty).toBe(true);
|
||||
});
|
||||
|
||||
it('should check multiple touched layouts', () => {
|
||||
const store = createStore();
|
||||
const wrapper = getWrapper(store);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('navigationMenuItems'), {
|
||||
current: [],
|
||||
draft: [],
|
||||
status: 'up-to-date',
|
||||
});
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
store.set(activeCustomizationPageLayoutIdsState.atom, [
|
||||
PAGE_LAYOUT_ID_1,
|
||||
PAGE_LAYOUT_ID_2,
|
||||
]);
|
||||
|
||||
// First layout is clean
|
||||
store.set(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
MOCK_PAGE_LAYOUT,
|
||||
);
|
||||
store.set(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_1,
|
||||
}),
|
||||
MOCK_PAGE_LAYOUT,
|
||||
);
|
||||
|
||||
// Second layout is dirty
|
||||
const secondLayout: PageLayout = {
|
||||
...MOCK_PAGE_LAYOUT,
|
||||
id: PAGE_LAYOUT_ID_2,
|
||||
name: 'Second Layout',
|
||||
};
|
||||
store.set(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_2,
|
||||
}),
|
||||
secondLayout,
|
||||
);
|
||||
store.set(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: PAGE_LAYOUT_ID_2,
|
||||
}),
|
||||
{ ...secondLayout, name: 'Modified Second' },
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useIsLayoutCustomizationDirty(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isDirty).toBe(true);
|
||||
});
|
||||
});
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
import { useExitLayoutCustomizationMode } from '@/layout-customization/hooks/useExitLayoutCustomizationMode';
|
||||
import { type DraftPageLayout } from '@/page-layout/types/DraftPageLayout';
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { fieldsWidgetEditorModeDraftComponentState } from '@/page-layout/states/fieldsWidgetEditorModeDraftComponentState';
|
||||
import { fieldsWidgetEditorModePersistedComponentState } from '@/page-layout/states/fieldsWidgetEditorModePersistedComponentState';
|
||||
import { fieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/fieldsWidgetGroupsDraftComponentState';
|
||||
import { fieldsWidgetGroupsPersistedComponentState } from '@/page-layout/states/fieldsWidgetGroupsPersistedComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsDraftComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsDraftComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsPersistedComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsPersistedComponentState';
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLayoutToTabLayouts';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCancelLayoutCustomization = () => {
|
||||
const store = useStore();
|
||||
const { exitLayoutCustomizationMode } = useExitLayoutCustomizationMode();
|
||||
|
||||
const cancel = useCallback(() => {
|
||||
const activePageLayoutIds = store.get(
|
||||
activeCustomizationPageLayoutIdsState.atom,
|
||||
);
|
||||
|
||||
for (const pageLayoutId of activePageLayoutIds) {
|
||||
const persisted = store.get(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isDefined(persisted)) {
|
||||
store.set(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
{
|
||||
id: persisted.id,
|
||||
name: persisted.name,
|
||||
type: persisted.type,
|
||||
objectMetadataId: persisted.objectMetadataId,
|
||||
tabs: persisted.tabs,
|
||||
defaultTabToFocusOnMobileAndSidePanelId:
|
||||
persisted.defaultTabToFocusOnMobileAndSidePanelId,
|
||||
} satisfies DraftPageLayout,
|
||||
);
|
||||
|
||||
store.set(
|
||||
pageLayoutCurrentLayoutsComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
convertPageLayoutToTabLayouts(persisted),
|
||||
);
|
||||
}
|
||||
|
||||
const fieldsWidgetGroupsPersisted = store.get(
|
||||
fieldsWidgetGroupsPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
store.set(
|
||||
fieldsWidgetGroupsDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
fieldsWidgetGroupsPersisted,
|
||||
);
|
||||
|
||||
const fieldsWidgetUngroupedFieldsPersisted = store.get(
|
||||
fieldsWidgetUngroupedFieldsPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
store.set(
|
||||
fieldsWidgetUngroupedFieldsDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
fieldsWidgetUngroupedFieldsPersisted,
|
||||
);
|
||||
|
||||
const fieldsWidgetEditorModePersisted = store.get(
|
||||
fieldsWidgetEditorModePersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
store.set(
|
||||
fieldsWidgetEditorModeDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
fieldsWidgetEditorModePersisted,
|
||||
);
|
||||
}
|
||||
|
||||
exitLayoutCustomizationMode();
|
||||
}, [store, exitLayoutCustomizationMode]);
|
||||
|
||||
return { cancel };
|
||||
};
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/common/utils/filterWorkspaceNavigationMenuItems';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/common/states/navigationMenuItemsDraftState';
|
||||
import { navigationMenuItemsSelector } from '@/navigation-menu-item/common/states/navigationMenuItemsSelector';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useEnterLayoutCustomizationMode = () => {
|
||||
const store = useStore();
|
||||
|
||||
const enterLayoutCustomizationMode = useCallback(() => {
|
||||
const isLayoutCustomizationModeAlreadyEnabled = store.get(
|
||||
isLayoutCustomizationModeEnabledState.atom,
|
||||
);
|
||||
|
||||
if (isLayoutCustomizationModeAlreadyEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const prefetchNavigationMenuItems = store.get(
|
||||
navigationMenuItemsSelector.atom,
|
||||
);
|
||||
const workspaceNavigationMenuItems = filterWorkspaceNavigationMenuItems(
|
||||
prefetchNavigationMenuItems,
|
||||
);
|
||||
store.set(navigationMenuItemsDraftState.atom, workspaceNavigationMenuItems);
|
||||
|
||||
store.set(activeCustomizationPageLayoutIdsState.atom, []);
|
||||
|
||||
store.set(isLayoutCustomizationModeEnabledState.atom, true);
|
||||
}, [store]);
|
||||
|
||||
return { enterLayoutCustomizationMode };
|
||||
};
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/common/states/navigationMenuItemsDraftState';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/common/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useExitLayoutCustomizationMode = () => {
|
||||
const store = useStore();
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const setNavigationMenuItemsDraft = useSetAtomState(
|
||||
navigationMenuItemsDraftState,
|
||||
);
|
||||
const setSelectedNavigationMenuItemInEditMode = useSetAtomState(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
const setIsLayoutCustomizationModeEnabled = useSetAtomState(
|
||||
isLayoutCustomizationModeEnabledState,
|
||||
);
|
||||
|
||||
const exitLayoutCustomizationMode = useCallback(() => {
|
||||
setNavigationMenuItemsDraft(null);
|
||||
setSelectedNavigationMenuItemInEditMode(null);
|
||||
|
||||
store.set(currentPageLayoutIdState.atom, null);
|
||||
store.set(activeCustomizationPageLayoutIdsState.atom, []);
|
||||
setIsLayoutCustomizationModeEnabled(false);
|
||||
closeSidePanelMenu();
|
||||
}, [
|
||||
setNavigationMenuItemsDraft,
|
||||
setSelectedNavigationMenuItemInEditMode,
|
||||
setIsLayoutCustomizationModeEnabled,
|
||||
closeSidePanelMenu,
|
||||
store,
|
||||
]);
|
||||
|
||||
return { exitLayoutCustomizationMode };
|
||||
};
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { type DraftPageLayout } from '@/page-layout/types/DraftPageLayout';
|
||||
import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/edit/hooks/useNavigationMenuItemsDraftState';
|
||||
import { fieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/fieldsWidgetGroupsDraftComponentState';
|
||||
import { fieldsWidgetGroupsPersistedComponentState } from '@/page-layout/states/fieldsWidgetGroupsPersistedComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsDraftComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsDraftComponentState';
|
||||
import { fieldsWidgetUngroupedFieldsPersistedComponentState } from '@/page-layout/states/fieldsWidgetUngroupedFieldsPersistedComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { atom, useAtomValue } from 'jotai';
|
||||
import { useMemo } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const useIsLayoutCustomizationDirty = () => {
|
||||
const { isDirty: isNavigationDirty } = useNavigationMenuItemsDraftState();
|
||||
|
||||
const isAnyPageLayoutDirtyAtom = useMemo(
|
||||
() =>
|
||||
atom((get) => {
|
||||
const activePageLayoutIds = get(
|
||||
activeCustomizationPageLayoutIdsState.atom,
|
||||
);
|
||||
|
||||
for (const pageLayoutId of activePageLayoutIds) {
|
||||
const draft = get(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
const persisted = get(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!isDefined(draft) || !isDefined(persisted)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const persistedAsDraft: DraftPageLayout = {
|
||||
id: persisted.id,
|
||||
name: persisted.name,
|
||||
type: persisted.type,
|
||||
objectMetadataId: persisted.objectMetadataId,
|
||||
tabs: persisted.tabs,
|
||||
defaultTabToFocusOnMobileAndSidePanelId:
|
||||
persisted.defaultTabToFocusOnMobileAndSidePanelId,
|
||||
};
|
||||
|
||||
if (!isDeeplyEqual(draft, persistedAsDraft)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const fieldsWidgetGroupsDraft = get(
|
||||
fieldsWidgetGroupsDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
const fieldsWidgetGroupsPersisted = get(
|
||||
fieldsWidgetGroupsPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
!isDeeplyEqual(fieldsWidgetGroupsDraft, fieldsWidgetGroupsPersisted)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ungroupedFieldsDraft = get(
|
||||
fieldsWidgetUngroupedFieldsDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
const ungroupedFieldsPersisted = get(
|
||||
fieldsWidgetUngroupedFieldsPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!isDeeplyEqual(ungroupedFieldsDraft, ungroupedFieldsPersisted)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
const isAnyPageLayoutDirty = useAtomValue(isAnyPageLayoutDirtyAtom);
|
||||
|
||||
return { isDirty: isNavigationDirty || isAnyPageLayoutDirty };
|
||||
};
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
import { useExitLayoutCustomizationMode } from '@/layout-customization/hooks/useExitLayoutCustomizationMode';
|
||||
import { activeCustomizationPageLayoutIdsState } from '@/layout-customization/states/activeCustomizationPageLayoutIdsState';
|
||||
import { useSaveNavigationMenuItemsDraft } from '@/navigation-menu-item/edit/hooks/useSaveNavigationMenuItemsDraft';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/common/states/navigationMenuItemsDraftState';
|
||||
import { navigationMenuItemsSelector } from '@/navigation-menu-item/common/states/navigationMenuItemsSelector';
|
||||
import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/common/utils/filterWorkspaceNavigationMenuItems';
|
||||
import { useSaveFieldsWidgetGroups } from '@/page-layout/hooks/useSaveFieldsWidgetGroups';
|
||||
import { useUpdatePageLayoutWithTabsAndWidgets } from '@/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets';
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { type DraftPageLayout } from '@/page-layout/types/DraftPageLayout';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { convertPageLayoutDraftToUpdateInput } from '@/page-layout/utils/convertPageLayoutDraftToUpdateInput';
|
||||
import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLayoutToTabLayouts';
|
||||
import { reInjectDynamicRelationWidgetsFromDraft } from '@/page-layout/utils/reInjectDynamicRelationWidgetsFromDraft';
|
||||
import { transformPageLayout } from '@/page-layout/utils/transformPageLayout';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { PageLayoutType } from '~/generated-metadata/graphql';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
export const useSaveLayoutCustomization = () => {
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const store = useStore();
|
||||
const { t } = useLingui();
|
||||
|
||||
const { saveDraft } = useSaveNavigationMenuItemsDraft();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { updatePageLayoutWithTabsAndWidgets } =
|
||||
useUpdatePageLayoutWithTabsAndWidgets();
|
||||
const { exitLayoutCustomizationMode } = useExitLayoutCustomizationMode();
|
||||
const { saveFieldsWidgetGroups } = useSaveFieldsWidgetGroups();
|
||||
|
||||
const save = useCallback(async () => {
|
||||
setIsSaving(true);
|
||||
try {
|
||||
const navigationDraft = store.get(navigationMenuItemsDraftState.atom);
|
||||
const prefetchItems = store.get(navigationMenuItemsSelector.atom);
|
||||
const workspaceItems = filterWorkspaceNavigationMenuItems(prefetchItems);
|
||||
const isNavigationDirty =
|
||||
isDefined(navigationDraft) &&
|
||||
!isDeeplyEqual(navigationDraft, workspaceItems);
|
||||
|
||||
// TODO: consider a single server mutation (e.g. saveLayoutCustomization)
|
||||
// that saves navigation + page layouts + field widgets in one transaction.
|
||||
// Currently, partial failure leaves mixed state — navigation may commit
|
||||
// while page layouts fail.
|
||||
if (isNavigationDirty) {
|
||||
await saveDraft();
|
||||
}
|
||||
|
||||
const activePageLayoutIds = store.get(
|
||||
activeCustomizationPageLayoutIdsState.atom,
|
||||
);
|
||||
let hasAnyFailure = false;
|
||||
|
||||
for (const pageLayoutId of activePageLayoutIds) {
|
||||
const draft = store.get(
|
||||
pageLayoutDraftComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
const persisted = store.get(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!isDefined(draft) || !isDefined(persisted)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const persistedAsDraft: DraftPageLayout = {
|
||||
id: persisted.id,
|
||||
name: persisted.name,
|
||||
type: persisted.type,
|
||||
objectMetadataId: persisted.objectMetadataId,
|
||||
tabs: persisted.tabs,
|
||||
defaultTabToFocusOnMobileAndSidePanelId:
|
||||
persisted.defaultTabToFocusOnMobileAndSidePanelId,
|
||||
};
|
||||
|
||||
const isPageLayoutStructureDirty = !isDeeplyEqual(
|
||||
draft,
|
||||
persistedAsDraft,
|
||||
);
|
||||
|
||||
if (isPageLayoutStructureDirty) {
|
||||
const updateInput = convertPageLayoutDraftToUpdateInput(draft);
|
||||
const result = await updatePageLayoutWithTabsAndWidgets(
|
||||
pageLayoutId,
|
||||
updateInput,
|
||||
);
|
||||
|
||||
if (result.status === 'successful') {
|
||||
const updatedPageLayout =
|
||||
result.response.data?.updatePageLayoutWithTabsAndWidgets;
|
||||
|
||||
if (isDefined(updatedPageLayout)) {
|
||||
const persistedLayout: PageLayout =
|
||||
transformPageLayout(updatedPageLayout);
|
||||
|
||||
const pageLayoutToPersist =
|
||||
persistedLayout.type === PageLayoutType.RECORD_PAGE
|
||||
? reInjectDynamicRelationWidgetsFromDraft(
|
||||
persistedLayout,
|
||||
draft,
|
||||
)
|
||||
: persistedLayout;
|
||||
|
||||
store.set(
|
||||
pageLayoutPersistedComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
pageLayoutToPersist,
|
||||
);
|
||||
store.set(
|
||||
pageLayoutCurrentLayoutsComponentState.atomFamily({
|
||||
instanceId: pageLayoutId,
|
||||
}),
|
||||
convertPageLayoutToTabLayouts(pageLayoutToPersist),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// goes away with a single server mutation (see TODO above)
|
||||
hasAnyFailure = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
await saveFieldsWidgetGroups(pageLayoutId);
|
||||
}
|
||||
|
||||
if (hasAnyFailure) {
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Some layout changes could not be saved`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
exitLayoutCustomizationMode();
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to save layout customization`,
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
}, [
|
||||
saveDraft,
|
||||
updatePageLayoutWithTabsAndWidgets,
|
||||
saveFieldsWidgetGroups,
|
||||
exitLayoutCustomizationMode,
|
||||
enqueueErrorSnackBar,
|
||||
store,
|
||||
t,
|
||||
]);
|
||||
|
||||
return { save, isSaving };
|
||||
};
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
||||
export const activeCustomizationPageLayoutIdsState = createAtomState<string[]>({
|
||||
key: 'activeCustomizationPageLayoutIdsState',
|
||||
defaultValue: [],
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
||||
export const isLayoutCustomizationModeEnabledState = createAtomState<boolean>({
|
||||
key: 'isLayoutCustomizationModeEnabledState',
|
||||
defaultValue: false,
|
||||
});
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
||||
export const isNavigationMenuInEditModeState = createAtomState<boolean>({
|
||||
key: 'isNavigationMenuInEditModeState',
|
||||
defaultValue: false,
|
||||
});
|
||||
+4
-6
@@ -4,6 +4,7 @@ import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconFolder, IconLink, useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { useEnterLayoutCustomizationMode } from '@/layout-customization/hooks/useEnterLayoutCustomizationMode';
|
||||
import { ADD_TO_NAV_SOURCE_DROPPABLE_ID } from '@/navigation-menu-item/common/constants/AddToNavSourceDroppableId';
|
||||
import { NavigationMenuItemType } from 'twenty-shared/types';
|
||||
import { useAddFolderToNavigationMenuDraft } from '@/navigation-menu-item/edit/folder/hooks/useAddFolderToNavigationMenuDraft';
|
||||
@@ -14,7 +15,6 @@ import { useAddViewToNavigationMenuDraft } from '@/navigation-menu-item/edit/vie
|
||||
import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/edit/hooks/useNavigationMenuItemsDraftState';
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/edit/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addToNavPayloadRegistryState } from '@/navigation-menu-item/common/states/addToNavPayloadRegistryState';
|
||||
import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/common/states/isNavigationMenuInEditModeState';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/common/states/navigationMenuItemsDraftState';
|
||||
import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/common/states/openNavigationMenuItemFolderIdsState';
|
||||
import { getObjectMetadataIdsInDraft } from '@/navigation-menu-item/common/utils/getObjectMetadataIdsInDraft';
|
||||
@@ -43,9 +43,7 @@ export const useHandleAddToNavigationDrop = () => {
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const views = useAtomStateValue(viewsSelector);
|
||||
const { getIcon } = useIcons();
|
||||
const setIsNavigationMenuInEditMode = useSetAtomState(
|
||||
isNavigationMenuInEditModeState,
|
||||
);
|
||||
const { enterLayoutCustomizationMode } = useEnterLayoutCustomizationMode();
|
||||
const setOpenNavigationMenuItemFolderIds = useSetAtomState(
|
||||
openNavigationMenuItemFolderIdsState,
|
||||
);
|
||||
@@ -92,7 +90,7 @@ export const useHandleAddToNavigationDrop = () => {
|
||||
'itemId'
|
||||
>,
|
||||
) => {
|
||||
setIsNavigationMenuInEditMode(true);
|
||||
enterLayoutCustomizationMode();
|
||||
openNavigationMenuItemInSidePanel({ ...options, itemId: newItemId });
|
||||
};
|
||||
|
||||
@@ -216,7 +214,7 @@ export const useHandleAddToNavigationDrop = () => {
|
||||
objectMetadataItems,
|
||||
openNavigationMenuItemInSidePanel,
|
||||
setOpenNavigationMenuItemFolderIds,
|
||||
setIsNavigationMenuInEditMode,
|
||||
enterLayoutCustomizationMode,
|
||||
workspaceNavigationMenuItems,
|
||||
store,
|
||||
],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user