fix(ui): refine create task actions and relocate icon sources (#1500)
No files matched your search
@@ -7,7 +7,7 @@ description: Design or revise Gopeed file-classification icons as one cohesive S
|
|||||||
|
|
||||||
Maintain Gopeed's file-classification visual language and its deterministic SVG → TTF → Flutter `IconData` pipeline.
|
Maintain Gopeed's file-classification visual language and its deterministic SVG → TTF → Flutter `IconData` pipeline.
|
||||||
|
|
||||||
The canonical editable materials live in `design/file-category-icons/`, outside the Flutter project. Read its `README.md` before changing any source. Do not add that directory to Flutter assets.
|
The canonical editable materials live in `design/file-category-icons/` as tooling-only sources inside the Flutter project. Read its `README.md` before changing any source. Do not add that directory to Flutter assets.
|
||||||
|
|
||||||
## Classification grammar
|
## Classification grammar
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ Use [assets/manifest.example.json](assets/manifest.example.json) and [assets/fol
|
|||||||
## Invariants
|
## Invariants
|
||||||
|
|
||||||
- Existing codepoints are API: never renumber or reuse one unless the user explicitly approves a breaking migration.
|
- Existing codepoints are API: never renumber or reuse one unless the user explicitly approves a breaking migration.
|
||||||
- `design/file-category-icons/` is the sole editable source of truth. Flutter keeps only the generated runtime TTF and Dart constants.
|
- `design/file-category-icons/` is the sole editable source of truth. The packaged Flutter runtime uses only the generated TTF and Dart constants.
|
||||||
- Never add the design-material directory to `pubspec.yaml`; it must remain outside the packaged Flutter asset graph.
|
- Never add the design-material directory to `pubspec.yaml`; it must remain outside the packaged Flutter asset graph.
|
||||||
- The manifest is the source of truth. Do not hand-edit generated Dart constants or patch the binary font.
|
- The manifest is the source of truth. Do not hand-edit generated Dart constants or patch the binary font.
|
||||||
- Keep icon names lowercase `snake_case`; the generator emits lowerCamelCase Dart fields.
|
- Keep icon names lowercase `snake_case`; the generator emits lowerCamelCase Dart fields.
|
||||||
|
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 818 B |
@@ -1,6 +1,6 @@
|
|||||||
# 文件分类图标源物料
|
# 文件分类图标源物料
|
||||||
|
|
||||||
此目录是 Gopeed 文件分类图标的唯一源物料目录,位于 Flutter 工程之外,不得加入 `ui/flutter/pubspec.yaml` 的 `assets` 配置。
|
此目录是 Gopeed 文件分类图标的唯一源物料目录。它位于 Flutter 工程内,但只用于设计和生成流程,不得加入 `pubspec.yaml` 的 `assets` 配置。
|
||||||
|
|
||||||
## 维护限制
|
## 维护限制
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
## 生成产物
|
## 生成产物
|
||||||
|
|
||||||
- Flutter 字体:`ui/flutter/assets/fonts/GopeedIcons.ttf`
|
- Flutter 字体:`assets/fonts/GopeedIcons.ttf`
|
||||||
- Flutter 常量:`ui/flutter/lib/core/icons/gopeed_icons.dart`
|
- Flutter 常量:`lib/core/icons/gopeed_icons.dart`
|
||||||
|
|
||||||
所有修改都应遵循:
|
所有修改都应遵循:
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"fontFamily": "GopeedIcons",
|
"fontFamily": "GopeedIcons",
|
||||||
"fontOutput": "../../ui/flutter/assets/fonts/GopeedIcons.ttf",
|
"fontOutput": "../../assets/fonts/GopeedIcons.ttf",
|
||||||
"dartOutput": "../../ui/flutter/lib/core/icons/gopeed_icons.dart",
|
"dartOutput": "../../lib/core/icons/gopeed_icons.dart",
|
||||||
"previewOutput": "preview/gopeed_icons_preview.png",
|
"previewOutput": "preview/gopeed_icons_preview.png",
|
||||||
"dartClass": "GopeedIcons",
|
"dartClass": "GopeedIcons",
|
||||||
"codepointStart": "0xE900",
|
"codepointStart": "0xE900",
|
||||||
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 526 B |
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 387 B |
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 597 B |
|
Before Width: | Height: | Size: 495 B After Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 293 B After Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 355 B |
|
Before Width: | Height: | Size: 293 B After Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 262 B |
|
Before Width: | Height: | Size: 479 B After Width: | Height: | Size: 479 B |
|
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 467 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 472 B After Width: | Height: | Size: 472 B |
|
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
|
Before Width: | Height: | Size: 723 B After Width: | Height: | Size: 723 B |
@@ -29,7 +29,6 @@ import '../../../../shared/theme/app_design_tokens.dart';
|
|||||||
import '../../../../shared/theme/app_palette.dart';
|
import '../../../../shared/theme/app_palette.dart';
|
||||||
import '../../../../shared/widgets/app_choice_segmented_control.dart';
|
import '../../../../shared/widgets/app_choice_segmented_control.dart';
|
||||||
import '../../../../shared/widgets/app_http_headers_editor.dart';
|
import '../../../../shared/widgets/app_http_headers_editor.dart';
|
||||||
import '../../../../shared/widgets/app_loading_button.dart';
|
|
||||||
import '../../../../shared/widgets/app_number_input.dart';
|
import '../../../../shared/widgets/app_number_input.dart';
|
||||||
import '../../../../shared/widgets/app_path_picker_field.dart';
|
import '../../../../shared/widgets/app_path_picker_field.dart';
|
||||||
import '../../../../shared/widgets/app_text_field.dart';
|
import '../../../../shared/widgets/app_text_field.dart';
|
||||||
@@ -38,8 +37,8 @@ import '../../../../shared/widgets/app_toast.dart';
|
|||||||
import '../../../../l10n/l10n.dart';
|
import '../../../../l10n/l10n.dart';
|
||||||
import '../../../../util/util.dart';
|
import '../../../../util/util.dart';
|
||||||
import '../../application/pending_create_task.dart';
|
import '../../application/pending_create_task.dart';
|
||||||
|
import '../widgets/create_task_action_buttons.dart';
|
||||||
import '../widgets/resolve_file_tree.dart';
|
import '../widgets/resolve_file_tree.dart';
|
||||||
import '../widgets/resolve_task_actions.dart';
|
|
||||||
|
|
||||||
class CreateTaskWindowPage extends ConsumerStatefulWidget {
|
class CreateTaskWindowPage extends ConsumerStatefulWidget {
|
||||||
const CreateTaskWindowPage({super.key, this.windowController, this.initialTask});
|
const CreateTaskWindowPage({super.key, this.windowController, this.initialTask});
|
||||||
@@ -696,17 +695,14 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SecondaryButton(
|
CreateTaskActionButtons(
|
||||||
onPressed: _creating ? null : _closeWindow,
|
submitting: _creating,
|
||||||
child: SizedBox(width: 68, child: Center(child: Text(context.l10n.cancel))),
|
onCancel: _closeWindow,
|
||||||
),
|
onSubmit: _confirm,
|
||||||
const SizedBox(width: 12),
|
cancelLabel: context.l10n.cancel,
|
||||||
AppLoadingButton(
|
submitLabel: context.l10n.confirm,
|
||||||
key: const ValueKey('create-task-confirm-button'),
|
cancelButtonKey: const ValueKey('create-task-cancel-button'),
|
||||||
onPressed: _confirm,
|
submitButtonKey: const ValueKey('create-task-confirm-button'),
|
||||||
loading: _creating,
|
|
||||||
variant: AppLoadingButtonVariant.primary,
|
|
||||||
child: SizedBox(width: 68, child: Center(child: Text(context.l10n.confirm))),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -1159,10 +1155,14 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
flutter.Flexible(
|
flutter.Flexible(
|
||||||
child: ResolveTaskActions(
|
child: CreateTaskActionButtons(
|
||||||
submitting: submitting,
|
submitting: submitting,
|
||||||
onCancel: () => closeOverlay(dialogContext, false),
|
onCancel: () => closeOverlay(dialogContext, false),
|
||||||
onCreate: submit,
|
onSubmit: submit,
|
||||||
|
cancelLabel: dialogContext.l10n.cancel,
|
||||||
|
submitLabel: dialogContext.l10n.createAction,
|
||||||
|
cancelButtonKey: const ValueKey('resolve-cancel-button'),
|
||||||
|
submitButtonKey: const ValueKey('resolve-create-button'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1205,7 +1205,7 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
|||||||
width: contentWidth,
|
width: contentWidth,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: Text(dialogContext.l10n.createHistory)),
|
Expanded(child: Text(dialogContext.l10n.historyLinks)),
|
||||||
AppTooltip(
|
AppTooltip(
|
||||||
message: dialogContext.l10n.clearHistory,
|
message: dialogContext.l10n.clearHistory,
|
||||||
child: GhostButton(
|
child: GhostButton(
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter/widgets.dart' as flutter;
|
||||||
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||||
|
|
||||||
|
import '../../../../shared/theme/app_design_tokens.dart';
|
||||||
|
import '../../../../shared/widgets/app_loading_button.dart';
|
||||||
|
|
||||||
|
class CreateTaskActionButtons extends StatelessWidget {
|
||||||
|
const CreateTaskActionButtons({
|
||||||
|
super.key,
|
||||||
|
required this.submitting,
|
||||||
|
required this.onCancel,
|
||||||
|
required this.onSubmit,
|
||||||
|
required this.cancelLabel,
|
||||||
|
required this.submitLabel,
|
||||||
|
this.cancelButtonKey,
|
||||||
|
this.submitButtonKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool submitting;
|
||||||
|
final VoidCallback onCancel;
|
||||||
|
final VoidCallback onSubmit;
|
||||||
|
final String cancelLabel;
|
||||||
|
final String submitLabel;
|
||||||
|
final Key? cancelButtonKey;
|
||||||
|
final Key? submitButtonKey;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return flutter.Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SecondaryButton(
|
||||||
|
key: cancelButtonKey,
|
||||||
|
onPressed: submitting ? null : onCancel,
|
||||||
|
child: SizedBox(
|
||||||
|
width: _actionContentWidth,
|
||||||
|
child: Center(child: Text(cancelLabel)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: AppDesignTokens.space12),
|
||||||
|
AppLoadingButton(
|
||||||
|
key: submitButtonKey,
|
||||||
|
onPressed: onSubmit,
|
||||||
|
loading: submitting,
|
||||||
|
variant: AppLoadingButtonVariant.primary,
|
||||||
|
child: SizedBox(
|
||||||
|
width: _actionContentWidth,
|
||||||
|
child: Center(child: Text(submitLabel)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _actionContentWidth = 68.0;
|
||||||
@@ -189,42 +189,48 @@ class _TreeFooter extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final palette = AppPalette.of(context);
|
final palette = AppPalette.of(context);
|
||||||
final filters = _FileTypeFilterGroup(
|
final filters = KeyedSubtree(
|
||||||
videoActive: activeTypeFilters.contains(_FileTypeFilter.video),
|
key: const ValueKey('resolve-tree-filters'),
|
||||||
audioActive: activeTypeFilters.contains(_FileTypeFilter.audio),
|
child: _FileTypeFilterGroup(
|
||||||
imageActive: activeTypeFilters.contains(_FileTypeFilter.image),
|
videoActive: activeTypeFilters.contains(_FileTypeFilter.video),
|
||||||
onSelectVideo: onSelectVideo,
|
audioActive: activeTypeFilters.contains(_FileTypeFilter.audio),
|
||||||
onSelectAudio: onSelectAudio,
|
imageActive: activeTypeFilters.contains(_FileTypeFilter.image),
|
||||||
onSelectImage: onSelectImage,
|
onSelectVideo: onSelectVideo,
|
||||||
|
onSelectAudio: onSelectAudio,
|
||||||
|
onSelectImage: onSelectImage,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final stats = Row(
|
final statsStyle = TextStyle(color: palette.textSecondary, fontSize: 12, fontWeight: FontWeight.w600);
|
||||||
mainAxisSize: MainAxisSize.min,
|
final selectedLabel = context.l10n.selectedCount(selectedCount, totalCount);
|
||||||
|
final sizeLabel = unknownSize ? context.l10n.unknownSize : Util.fmtByte(selectedSize);
|
||||||
|
final baseline = MediaQuery.textScalerOf(context).scale(statsStyle.fontSize!);
|
||||||
|
final stats = Wrap(
|
||||||
|
key: const ValueKey('resolve-tree-selection-stats'),
|
||||||
|
alignment: WrapAlignment.end,
|
||||||
|
spacing: AppDesignTokens.space8,
|
||||||
|
runSpacing: AppDesignTokens.space4,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Baseline(
|
||||||
context.l10n.selectedCount(selectedCount, totalCount),
|
baseline: baseline,
|
||||||
style: TextStyle(color: palette.textSecondary, fontSize: 12, fontWeight: FontWeight.w600),
|
baselineType: TextBaseline.alphabetic,
|
||||||
|
child: Text(key: const ValueKey('resolve-tree-selected-count'), selectedLabel, style: statsStyle),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
Baseline(
|
||||||
Text(
|
baseline: baseline,
|
||||||
unknownSize ? context.l10n.unknownSize : Util.fmtByte(selectedSize),
|
baselineType: TextBaseline.alphabetic,
|
||||||
style: TextStyle(color: palette.textSecondary, fontSize: 12, fontWeight: FontWeight.w600),
|
child: Text(key: const ValueKey('resolve-tree-selected-size'), sizeLabel, style: statsStyle),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
return OverflowBar(
|
||||||
if (constraints.maxWidth < 360) {
|
key: const ValueKey('resolve-tree-footer'),
|
||||||
return Column(
|
spacing: AppDesignTokens.space8,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
alignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
overflowAlignment: OverflowBarAlignment.end,
|
||||||
Align(alignment: Alignment.centerLeft, child: filters),
|
overflowSpacing: AppDesignTokens.space4,
|
||||||
const SizedBox(height: 4),
|
children: [filters, stats],
|
||||||
Align(alignment: Alignment.centerRight, child: stats),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Row(crossAxisAlignment: CrossAxisAlignment.center, children: [filters, const Spacer(), stats]);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,7 +296,11 @@ class _FilterDivider extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(width: 1, height: 18, child: ColoredBox(color: color));
|
return SizedBox(
|
||||||
|
width: _fileTypeFilterDividerWidth,
|
||||||
|
height: 18,
|
||||||
|
child: ColoredBox(color: color),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +315,7 @@ class _FilterButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final palette = AppPalette.of(context);
|
final palette = AppPalette.of(context);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 40,
|
width: _fileTypeFilterButtonWidth,
|
||||||
height: 28,
|
height: 28,
|
||||||
child: DecoratedBox(
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(color: active ? palette.filterActiveBg : null),
|
decoration: BoxDecoration(color: active ? palette.filterActiveBg : null),
|
||||||
@@ -340,3 +350,5 @@ const _audioExts = <String>{'mp3', 'flac', 'wav', 'aac', 'm4a', 'ogg', 'ape'};
|
|||||||
const _imageExts = <String>{'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'};
|
const _imageExts = <String>{'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'};
|
||||||
const _resolveTreeRowHeight = 36.0;
|
const _resolveTreeRowHeight = 36.0;
|
||||||
const _resolveFileNameStyle = TextStyle(fontSize: 14, height: 1.25);
|
const _resolveFileNameStyle = TextStyle(fontSize: 14, height: 1.25);
|
||||||
|
const _fileTypeFilterButtonWidth = 40.0;
|
||||||
|
const _fileTypeFilterDividerWidth = 1.0;
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
|
||||||
import 'package:flutter/widgets.dart' as flutter;
|
|
||||||
|
|
||||||
import '../../../../l10n/l10n.dart';
|
|
||||||
import '../../../../shared/theme/app_design_tokens.dart';
|
|
||||||
import '../../../../shared/widgets/app_loading_button.dart';
|
|
||||||
|
|
||||||
class ResolveTaskActions extends StatelessWidget {
|
|
||||||
const ResolveTaskActions({super.key, required this.submitting, required this.onCancel, required this.onCreate});
|
|
||||||
|
|
||||||
final bool submitting;
|
|
||||||
final VoidCallback onCancel;
|
|
||||||
final VoidCallback onCreate;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// Size both actions from the wider translated label, including while the
|
|
||||||
// create button replaces its label with a loader.
|
|
||||||
return IntrinsicWidth(
|
|
||||||
child: flutter.Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
flutter.Expanded(
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(minWidth: AppDesignTokens.dialogActionMinWidth),
|
|
||||||
child: SecondaryButton(
|
|
||||||
key: const ValueKey('resolve-cancel-button'),
|
|
||||||
onPressed: submitting ? null : onCancel,
|
|
||||||
child: Text(context.l10n.cancel, maxLines: 1, softWrap: false),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: AppDesignTokens.space8),
|
|
||||||
flutter.Expanded(
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(minWidth: AppDesignTokens.dialogActionMinWidth),
|
|
||||||
child: AppLoadingButton(
|
|
||||||
key: const ValueKey('resolve-create-button'),
|
|
||||||
onPressed: onCreate,
|
|
||||||
loading: submitting,
|
|
||||||
variant: AppLoadingButtonVariant.primary,
|
|
||||||
child: Text(context.l10n.createAction, maxLines: 1, softWrap: false),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count}",
|
"resolvedFileCount": "{count}",
|
||||||
"resourceHasNoFiles": "ولا توجد في هذا المورد قائمة ملف قابلة للاختيار",
|
"resourceHasNoFiles": "ولا توجد في هذا المورد قائمة ملف قابلة للاختيار",
|
||||||
"noFiles": "لا توجد ملفات",
|
"noFiles": "لا توجد ملفات",
|
||||||
"createHistory": "تاريخ الخلق",
|
"historyLinks": "روابط السجل",
|
||||||
"noHistory": "لا تاريخ",
|
"noHistory": "لا تاريخ",
|
||||||
"directDownloadDescription": "حل المشاكل وخلق المهام على الفور",
|
"directDownloadDescription": "حل المشاكل وخلق المهام على الفور",
|
||||||
"taskProgress": "التقدم المحرز",
|
"taskProgress": "التقدم المحرز",
|
||||||
|
|||||||
@@ -367,7 +367,7 @@
|
|||||||
"resolvedFileCount": "{count} fayl tapıldı",
|
"resolvedFileCount": "{count} fayl tapıldı",
|
||||||
"resourceHasNoFiles": "Bu resursda seçilə bilən fayl siyahısı yoxdur",
|
"resourceHasNoFiles": "Bu resursda seçilə bilən fayl siyahısı yoxdur",
|
||||||
"noFiles": "Fayl yoxdur",
|
"noFiles": "Fayl yoxdur",
|
||||||
"createHistory": "Tarixçə Yarat",
|
"historyLinks": "Tarixçə keçidləri",
|
||||||
"noHistory": "Tarixçə yoxdur",
|
"noHistory": "Tarixçə yoxdur",
|
||||||
"directDownloadDescription": "Təhlili keç və tapşırıqları dərhal yarat",
|
"directDownloadDescription": "Təhlili keç və tapşırıqları dərhal yarat",
|
||||||
"taskProgress": "Tapşırığın irəliləyişi",
|
"taskProgress": "Tapşırığın irəliləyişi",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count}",
|
"resolvedFileCount": "{count}",
|
||||||
"resourceHasNoFiles": "El recurs no té cap llista de fitxers per seleccionar",
|
"resourceHasNoFiles": "El recurs no té cap llista de fitxers per seleccionar",
|
||||||
"noFiles": "Sense fitxers",
|
"noFiles": "Sense fitxers",
|
||||||
"createHistory": "Crea un historial",
|
"historyLinks": "Enllaços de l'historial",
|
||||||
"noHistory": "Sense historial",
|
"noHistory": "Sense historial",
|
||||||
"directDownloadDescription": "Omet la resolució i crea les tasques immediatament",
|
"directDownloadDescription": "Omet la resolució i crea les tasques immediatament",
|
||||||
"taskProgress": "Progrés de la tasca",
|
"taskProgress": "Progrés de la tasca",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count}-Dateien behoben",
|
"resolvedFileCount": "{count}-Dateien behoben",
|
||||||
"resourceHasNoFiles": "Die Ressource verfügt über keine auswählbare Dateiliste",
|
"resourceHasNoFiles": "Die Ressource verfügt über keine auswählbare Dateiliste",
|
||||||
"noFiles": "Keine Dateien",
|
"noFiles": "Keine Dateien",
|
||||||
"createHistory": "Verlauf erstellen",
|
"historyLinks": "Verlaufslinks",
|
||||||
"noHistory": "Keine Historie",
|
"noHistory": "Keine Historie",
|
||||||
"directDownloadDescription": "Überspringen Sie die Lösung und erstellen Sie sofort Aufgaben",
|
"directDownloadDescription": "Überspringen Sie die Lösung und erstellen Sie sofort Aufgaben",
|
||||||
"taskProgress": "Aufgabenfortschritt",
|
"taskProgress": "Aufgabenfortschritt",
|
||||||
|
|||||||
@@ -367,7 +367,7 @@
|
|||||||
"resolvedFileCount": "{count, plural, =1{1 file resolved} other{{count} files resolved}}",
|
"resolvedFileCount": "{count, plural, =1{1 file resolved} other{{count} files resolved}}",
|
||||||
"resourceHasNoFiles": "The resource has no selectable file list",
|
"resourceHasNoFiles": "The resource has no selectable file list",
|
||||||
"noFiles": "No files",
|
"noFiles": "No files",
|
||||||
"createHistory": "Create History",
|
"historyLinks": "History Links",
|
||||||
"noHistory": "No history",
|
"noHistory": "No history",
|
||||||
"directDownloadDescription": "Skip resolving and create tasks immediately",
|
"directDownloadDescription": "Skip resolving and create tasks immediately",
|
||||||
"taskProgress": "Task progress",
|
"taskProgress": "Task progress",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} resueltos",
|
"resolvedFileCount": "{count} resueltos",
|
||||||
"resourceHasNoFiles": "El recurso no tiene lista de archivos seleccionable",
|
"resourceHasNoFiles": "El recurso no tiene lista de archivos seleccionable",
|
||||||
"noFiles": "No hay archivos",
|
"noFiles": "No hay archivos",
|
||||||
"createHistory": "Crear historia",
|
"historyLinks": "Enlaces del historial",
|
||||||
"noHistory": "No hay historia",
|
"noHistory": "No hay historia",
|
||||||
"directDownloadDescription": "Saltar a resolver y crear tareas inmediatamente",
|
"directDownloadDescription": "Saltar a resolver y crear tareas inmediatamente",
|
||||||
"taskProgress": "Progresos en la tarea",
|
"taskProgress": "Progresos en la tarea",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} فایل شناسایی شد",
|
"resolvedFileCount": "{count} فایل شناسایی شد",
|
||||||
"resourceHasNoFiles": "منبع هیچ لیست فایل قابل انتخاب ندارد",
|
"resourceHasNoFiles": "منبع هیچ لیست فایل قابل انتخاب ندارد",
|
||||||
"noFiles": "فایل ها",
|
"noFiles": "فایل ها",
|
||||||
"createHistory": "ایجاد تاریخ",
|
"historyLinks": "پیوندهای تاریخچه",
|
||||||
"noHistory": "تاریخ",
|
"noHistory": "تاریخ",
|
||||||
"directDownloadDescription": "پیاده سازی و ایجاد وظایف بلافاصله",
|
"directDownloadDescription": "پیاده سازی و ایجاد وظایف بلافاصله",
|
||||||
"taskProgress": "پیشرفت شغلی",
|
"taskProgress": "پیشرفت شغلی",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} résolus",
|
"resolvedFileCount": "{count} résolus",
|
||||||
"resourceHasNoFiles": "La ressource n'a pas de liste de fichiers sélectionnable",
|
"resourceHasNoFiles": "La ressource n'a pas de liste de fichiers sélectionnable",
|
||||||
"noFiles": "Aucun fichier",
|
"noFiles": "Aucun fichier",
|
||||||
"createHistory": "Créer l'historique",
|
"historyLinks": "Liens de l'historique",
|
||||||
"noHistory": "Pas d'histoire",
|
"noHistory": "Pas d'histoire",
|
||||||
"directDownloadDescription": "Sautez la résolution et créez immédiatement des tâches",
|
"directDownloadDescription": "Sautez la résolution et créez immédiatement des tâches",
|
||||||
"taskProgress": "Progrès accomplis dans la tâche",
|
"taskProgress": "Progrès accomplis dans la tâche",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} fájlok megoldva",
|
"resolvedFileCount": "{count} fájlok megoldva",
|
||||||
"resourceHasNoFiles": "Az erőforrásnak nincs kiválasztható fájllistája",
|
"resourceHasNoFiles": "Az erőforrásnak nincs kiválasztható fájllistája",
|
||||||
"noFiles": "Nincsenek fájlok",
|
"noFiles": "Nincsenek fájlok",
|
||||||
"createHistory": "Készítsen előzményeket",
|
"historyLinks": "Előzményhivatkozások",
|
||||||
"noHistory": "Nincs előzmény",
|
"noHistory": "Nincs előzmény",
|
||||||
"directDownloadDescription": "Hagyja ki a megoldást, és azonnal hozzon létre feladatokat",
|
"directDownloadDescription": "Hagyja ki a megoldást, és azonnal hozzon létre feladatokat",
|
||||||
"taskProgress": "A feladat előrehaladása",
|
"taskProgress": "A feladat előrehaladása",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} terselesaikan",
|
"resolvedFileCount": "{count} terselesaikan",
|
||||||
"resourceHasNoFiles": "Sumber daya tidak memiliki daftar berkas yang dapat dipilih",
|
"resourceHasNoFiles": "Sumber daya tidak memiliki daftar berkas yang dapat dipilih",
|
||||||
"noFiles": "Tidak ada berkas",
|
"noFiles": "Tidak ada berkas",
|
||||||
"createHistory": "Buat Riwayat",
|
"historyLinks": "Tautan Riwayat",
|
||||||
"noHistory": "Tidak ada sejarah",
|
"noHistory": "Tidak ada sejarah",
|
||||||
"directDownloadDescription": "Lewatkan pemecahan dan buat tugas segera",
|
"directDownloadDescription": "Lewatkan pemecahan dan buat tugas segera",
|
||||||
"taskProgress": "Kemajuan tugas",
|
"taskProgress": "Kemajuan tugas",
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"resolvedFileCount": "{count} risolti",
|
"resolvedFileCount": "{count} risolti",
|
||||||
"resourceHasNoFiles": "La risorsa non ha un elenco di file selezionabile",
|
"resourceHasNoFiles": "La risorsa non ha un elenco di file selezionabile",
|
||||||
"noFiles": "Nessun file",
|
"noFiles": "Nessun file",
|
||||||
"createHistory": "Creare la storia",
|
"historyLinks": "Link della cronologia",
|
||||||
"noHistory": "Nessuna storia",
|
"noHistory": "Nessuna storia",
|
||||||
"directDownloadDescription": "Salta la risoluzione e crea immediatamente i compiti",
|
"directDownloadDescription": "Salta la risoluzione e crea immediatamente i compiti",
|
||||||
"taskProgress": "Prospettive di attività",
|
"taskProgress": "Prospettive di attività",
|
||||||
|
|||||||