fix(ui): refine create task actions and relocate icon sources (#1500)

This commit is contained in:
Levi authored and GitHub committed 2026-09-11 08:00:03 +08:00
1 parent 8f9bac9e6b
commit 08fe4eef4e
64 files changed
+193 -139

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.
File renamed without changes.

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",
File renamed without changes.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 526 B

After

Width:  |  Height:  |  Size: 526 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 342 B

After

Width:  |  Height:  |  Size: 342 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 597 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 495 B

After

Width:  |  Height:  |  Size: 495 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 355 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 395 B

After

Width:  |  Height:  |  Size: 395 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 256 B

After

Width:  |  Height:  |  Size: 256 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 479 B

After

Width:  |  Height:  |  Size: 479 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 357 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 292 B

After

Width:  |  Height:  |  Size: 292 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 467 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 472 B

After

Width:  |  Height:  |  Size: 472 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

File renamed without changes.

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),
),
),
),
],
),
);
}
}
+1 -1
View File
@@ -353,7 +353,7 @@
"resolvedFileCount": "{count}", "resolvedFileCount": "{count}",
"resourceHasNoFiles": "ولا توجد في هذا المورد قائمة ملف قابلة للاختيار", "resourceHasNoFiles": "ولا توجد في هذا المورد قائمة ملف قابلة للاختيار",
"noFiles": "لا توجد ملفات", "noFiles": "لا توجد ملفات",
"createHistory": "تاريخ الخلق", "historyLinks": "روابط السجل",
"noHistory": "لا تاريخ", "noHistory": "لا تاريخ",
"directDownloadDescription": "حل المشاكل وخلق المهام على الفور", "directDownloadDescription": "حل المشاكل وخلق المهام على الفور",
"taskProgress": "التقدم المحرز", "taskProgress": "التقدم المحرز",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -353,7 +353,7 @@
"resolvedFileCount": "{count} فایل شناسایی شد", "resolvedFileCount": "{count} فایل شناسایی شد",
"resourceHasNoFiles": "منبع هیچ لیست فایل قابل انتخاب ندارد", "resourceHasNoFiles": "منبع هیچ لیست فایل قابل انتخاب ندارد",
"noFiles": "فایل ها", "noFiles": "فایل ها",
"createHistory": "ایجاد تاریخ", "historyLinks": "پیوندهای تاریخچه",
"noHistory": "تاریخ", "noHistory": "تاریخ",
"directDownloadDescription": "پیاده سازی و ایجاد وظایف بلافاصله", "directDownloadDescription": "پیاده سازی و ایجاد وظایف بلافاصله",
"taskProgress": "پیشرفت شغلی", "taskProgress": "پیشرفت شغلی",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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à",
Loaded 50 of 64 files, more files were not shown because too many files have changed in this diff. Show more