feat(04-07): add Phase 4 localization, shared dialogs, and example CSV resources
- Add 80+ Phase 4 EN/FR localization keys to Strings.resx and Strings.fr.resx (tabs, transfer, bulkmembers, bulksites, folderstruct, templates, bulk-shared, folderbrowser) - Add ResourceManager property accessors for all new keys to Strings.Designer.cs - Create ConfirmBulkOperationDialog (XAML + code-behind) with Proceed/Cancel buttons - Create FolderBrowserDialog (XAML + code-behind) with lazy-loading TreeView of SharePoint libraries/folders - Bundle bulk_add_members.csv, bulk_create_sites.csv, folder_structure.csv as EmbeddedResource in csproj
This commit is contained in:
91
SharepointToolbox/Localization/Strings.Designer.cs
generated
91
SharepointToolbox/Localization/Strings.Designer.cs
generated
@@ -136,5 +136,96 @@ namespace SharepointToolbox.Localization {
|
|||||||
public static string ph_dup_lib => ResourceManager.GetString("ph.dup.lib", resourceCulture) ?? string.Empty;
|
public static string ph_dup_lib => ResourceManager.GetString("ph.dup.lib", resourceCulture) ?? string.Empty;
|
||||||
public static string btn_run_scan => ResourceManager.GetString("btn.run.scan", resourceCulture) ?? string.Empty;
|
public static string btn_run_scan => ResourceManager.GetString("btn.run.scan", resourceCulture) ?? string.Empty;
|
||||||
public static string btn_open_results => ResourceManager.GetString("btn.open.results", resourceCulture) ?? string.Empty;
|
public static string btn_open_results => ResourceManager.GetString("btn.open.results", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Tab headers
|
||||||
|
public static string tab_transfer => ResourceManager.GetString("tab.transfer", resourceCulture) ?? string.Empty;
|
||||||
|
public static string tab_bulkMembers => ResourceManager.GetString("tab.bulkMembers", resourceCulture) ?? string.Empty;
|
||||||
|
public static string tab_bulkSites => ResourceManager.GetString("tab.bulkSites", resourceCulture) ?? string.Empty;
|
||||||
|
public static string tab_folderStructure => ResourceManager.GetString("tab.folderStructure", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Transfer tab
|
||||||
|
public static string transfer_sourcesite => ResourceManager.GetString("transfer.sourcesite", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_destsite => ResourceManager.GetString("transfer.destsite", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_sourcelibrary => ResourceManager.GetString("transfer.sourcelibrary", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_destlibrary => ResourceManager.GetString("transfer.destlibrary", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_sourcefolder => ResourceManager.GetString("transfer.sourcefolder", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_destfolder => ResourceManager.GetString("transfer.destfolder", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_mode => ResourceManager.GetString("transfer.mode", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_mode_copy => ResourceManager.GetString("transfer.mode.copy", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_mode_move => ResourceManager.GetString("transfer.mode.move", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_conflict => ResourceManager.GetString("transfer.conflict", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_conflict_skip => ResourceManager.GetString("transfer.conflict.skip", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_conflict_overwrite => ResourceManager.GetString("transfer.conflict.overwrite", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_conflict_rename => ResourceManager.GetString("transfer.conflict.rename", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_browse => ResourceManager.GetString("transfer.browse", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_start => ResourceManager.GetString("transfer.start", resourceCulture) ?? string.Empty;
|
||||||
|
public static string transfer_nofiles => ResourceManager.GetString("transfer.nofiles", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Bulk Members tab
|
||||||
|
public static string bulkmembers_import => ResourceManager.GetString("bulkmembers.import", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_example => ResourceManager.GetString("bulkmembers.example", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_execute => ResourceManager.GetString("bulkmembers.execute", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_preview => ResourceManager.GetString("bulkmembers.preview", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_groupname => ResourceManager.GetString("bulkmembers.groupname", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_groupurl => ResourceManager.GetString("bulkmembers.groupurl", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_email => ResourceManager.GetString("bulkmembers.email", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulkmembers_role => ResourceManager.GetString("bulkmembers.role", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Bulk Sites tab
|
||||||
|
public static string bulksites_import => ResourceManager.GetString("bulksites.import", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_example => ResourceManager.GetString("bulksites.example", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_execute => ResourceManager.GetString("bulksites.execute", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_preview => ResourceManager.GetString("bulksites.preview", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_name => ResourceManager.GetString("bulksites.name", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_alias => ResourceManager.GetString("bulksites.alias", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_type => ResourceManager.GetString("bulksites.type", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_owners => ResourceManager.GetString("bulksites.owners", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulksites_members => ResourceManager.GetString("bulksites.members", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Folder Structure tab
|
||||||
|
public static string folderstruct_import => ResourceManager.GetString("folderstruct.import", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderstruct_example => ResourceManager.GetString("folderstruct.example", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderstruct_execute => ResourceManager.GetString("folderstruct.execute", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderstruct_preview => ResourceManager.GetString("folderstruct.preview", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderstruct_library => ResourceManager.GetString("folderstruct.library", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderstruct_siteurl => ResourceManager.GetString("folderstruct.siteurl", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Templates tab
|
||||||
|
public static string templates_list => ResourceManager.GetString("templates.list", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_capture => ResourceManager.GetString("templates.capture", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_apply => ResourceManager.GetString("templates.apply", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_rename => ResourceManager.GetString("templates.rename", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_delete => ResourceManager.GetString("templates.delete", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_siteurl => ResourceManager.GetString("templates.siteurl", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_name => ResourceManager.GetString("templates.name", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_newtitle => ResourceManager.GetString("templates.newtitle", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_newalias => ResourceManager.GetString("templates.newalias", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_options => ResourceManager.GetString("templates.options", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_opt_libraries => ResourceManager.GetString("templates.opt.libraries", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_opt_folders => ResourceManager.GetString("templates.opt.folders", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_opt_permissions => ResourceManager.GetString("templates.opt.permissions", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_opt_logo => ResourceManager.GetString("templates.opt.logo", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_opt_settings => ResourceManager.GetString("templates.opt.settings", resourceCulture) ?? string.Empty;
|
||||||
|
public static string templates_empty => ResourceManager.GetString("templates.empty", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Shared bulk operation strings
|
||||||
|
public static string bulk_confirm_title => ResourceManager.GetString("bulk.confirm.title", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_confirm_proceed => ResourceManager.GetString("bulk.confirm.proceed", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_confirm_cancel => ResourceManager.GetString("bulk.confirm.cancel", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_confirm_message => ResourceManager.GetString("bulk.confirm.message", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_result_success => ResourceManager.GetString("bulk.result.success", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_result_allfailed => ResourceManager.GetString("bulk.result.allfailed", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_result_allsuccess => ResourceManager.GetString("bulk.result.allsuccess", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_exportfailed => ResourceManager.GetString("bulk.exportfailed", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_retryfailed => ResourceManager.GetString("bulk.retryfailed", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_validation_invalid => ResourceManager.GetString("bulk.validation.invalid", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_csvimport_title => ResourceManager.GetString("bulk.csvimport.title", resourceCulture) ?? string.Empty;
|
||||||
|
public static string bulk_csvimport_filter => ResourceManager.GetString("bulk.csvimport.filter", resourceCulture) ?? string.Empty;
|
||||||
|
|
||||||
|
// Phase 4: Folder browser dialog
|
||||||
|
public static string folderbrowser_title => ResourceManager.GetString("folderbrowser.title", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderbrowser_loading => ResourceManager.GetString("folderbrowser.loading", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderbrowser_select => ResourceManager.GetString("folderbrowser.select", resourceCulture) ?? string.Empty;
|
||||||
|
public static string folderbrowser_cancel => ResourceManager.GetString("folderbrowser.cancel", resourceCulture) ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,4 +221,87 @@
|
|||||||
<data name="ph.dup.lib" xml:space="preserve"><value>Tous (laisser vide)</value></data>
|
<data name="ph.dup.lib" xml:space="preserve"><value>Tous (laisser vide)</value></data>
|
||||||
<data name="btn.run.scan" xml:space="preserve"><value>Lancer l'analyse</value></data>
|
<data name="btn.run.scan" xml:space="preserve"><value>Lancer l'analyse</value></data>
|
||||||
<data name="btn.open.results" xml:space="preserve"><value>Ouvrir les résultats</value></data>
|
<data name="btn.open.results" xml:space="preserve"><value>Ouvrir les résultats</value></data>
|
||||||
|
<!-- Phase 4: Tab headers -->
|
||||||
|
<data name="tab.transfer" xml:space="preserve"><value>Transfert</value></data>
|
||||||
|
<data name="tab.bulkMembers" xml:space="preserve"><value>Ajout en masse</value></data>
|
||||||
|
<data name="tab.bulkSites" xml:space="preserve"><value>Sites en masse</value></data>
|
||||||
|
<data name="tab.folderStructure" xml:space="preserve"><value>Structure de dossiers</value></data>
|
||||||
|
<!-- Phase 4: Transfer tab -->
|
||||||
|
<data name="transfer.sourcesite" xml:space="preserve"><value>Site source</value></data>
|
||||||
|
<data name="transfer.destsite" xml:space="preserve"><value>Site destination</value></data>
|
||||||
|
<data name="transfer.sourcelibrary" xml:space="preserve"><value>Bibliotheque source</value></data>
|
||||||
|
<data name="transfer.destlibrary" xml:space="preserve"><value>Bibliotheque destination</value></data>
|
||||||
|
<data name="transfer.sourcefolder" xml:space="preserve"><value>Dossier source</value></data>
|
||||||
|
<data name="transfer.destfolder" xml:space="preserve"><value>Dossier destination</value></data>
|
||||||
|
<data name="transfer.mode" xml:space="preserve"><value>Mode de transfert</value></data>
|
||||||
|
<data name="transfer.mode.copy" xml:space="preserve"><value>Copier</value></data>
|
||||||
|
<data name="transfer.mode.move" xml:space="preserve"><value>Deplacer</value></data>
|
||||||
|
<data name="transfer.conflict" xml:space="preserve"><value>Politique de conflit</value></data>
|
||||||
|
<data name="transfer.conflict.skip" xml:space="preserve"><value>Ignorer</value></data>
|
||||||
|
<data name="transfer.conflict.overwrite" xml:space="preserve"><value>Ecraser</value></data>
|
||||||
|
<data name="transfer.conflict.rename" xml:space="preserve"><value>Renommer (ajouter suffixe)</value></data>
|
||||||
|
<data name="transfer.browse" xml:space="preserve"><value>Parcourir...</value></data>
|
||||||
|
<data name="transfer.start" xml:space="preserve"><value>Demarrer le transfert</value></data>
|
||||||
|
<data name="transfer.nofiles" xml:space="preserve"><value>Aucun fichier a transferer.</value></data>
|
||||||
|
<!-- Phase 4: Bulk Members tab -->
|
||||||
|
<data name="bulkmembers.import" xml:space="preserve"><value>Importer CSV</value></data>
|
||||||
|
<data name="bulkmembers.example" xml:space="preserve"><value>Charger l'exemple</value></data>
|
||||||
|
<data name="bulkmembers.execute" xml:space="preserve"><value>Ajouter les membres</value></data>
|
||||||
|
<data name="bulkmembers.preview" xml:space="preserve"><value>Apercu ({0} lignes, {1} valides, {2} invalides)</value></data>
|
||||||
|
<data name="bulkmembers.groupname" xml:space="preserve"><value>Nom du groupe</value></data>
|
||||||
|
<data name="bulkmembers.groupurl" xml:space="preserve"><value>URL du groupe</value></data>
|
||||||
|
<data name="bulkmembers.email" xml:space="preserve"><value>Courriel</value></data>
|
||||||
|
<data name="bulkmembers.role" xml:space="preserve"><value>Role</value></data>
|
||||||
|
<!-- Phase 4: Bulk Sites tab -->
|
||||||
|
<data name="bulksites.import" xml:space="preserve"><value>Importer CSV</value></data>
|
||||||
|
<data name="bulksites.example" xml:space="preserve"><value>Charger l'exemple</value></data>
|
||||||
|
<data name="bulksites.execute" xml:space="preserve"><value>Creer les sites</value></data>
|
||||||
|
<data name="bulksites.preview" xml:space="preserve"><value>Apercu ({0} lignes, {1} valides, {2} invalides)</value></data>
|
||||||
|
<data name="bulksites.name" xml:space="preserve"><value>Nom</value></data>
|
||||||
|
<data name="bulksites.alias" xml:space="preserve"><value>Alias</value></data>
|
||||||
|
<data name="bulksites.type" xml:space="preserve"><value>Type</value></data>
|
||||||
|
<data name="bulksites.owners" xml:space="preserve"><value>Proprietaires</value></data>
|
||||||
|
<data name="bulksites.members" xml:space="preserve"><value>Membres</value></data>
|
||||||
|
<!-- Phase 4: Folder Structure tab -->
|
||||||
|
<data name="folderstruct.import" xml:space="preserve"><value>Importer CSV</value></data>
|
||||||
|
<data name="folderstruct.example" xml:space="preserve"><value>Charger l'exemple</value></data>
|
||||||
|
<data name="folderstruct.execute" xml:space="preserve"><value>Creer les dossiers</value></data>
|
||||||
|
<data name="folderstruct.preview" xml:space="preserve"><value>Apercu ({0} dossiers a creer)</value></data>
|
||||||
|
<data name="folderstruct.library" xml:space="preserve"><value>Bibliotheque cible</value></data>
|
||||||
|
<data name="folderstruct.siteurl" xml:space="preserve"><value>URL du site</value></data>
|
||||||
|
<!-- Phase 4: Templates tab -->
|
||||||
|
<data name="templates.list" xml:space="preserve"><value>Modeles enregistres</value></data>
|
||||||
|
<data name="templates.capture" xml:space="preserve"><value>Capturer un modele</value></data>
|
||||||
|
<data name="templates.apply" xml:space="preserve"><value>Appliquer le modele</value></data>
|
||||||
|
<data name="templates.rename" xml:space="preserve"><value>Renommer</value></data>
|
||||||
|
<data name="templates.delete" xml:space="preserve"><value>Supprimer</value></data>
|
||||||
|
<data name="templates.siteurl" xml:space="preserve"><value>URL du site source</value></data>
|
||||||
|
<data name="templates.name" xml:space="preserve"><value>Nom du modele</value></data>
|
||||||
|
<data name="templates.newtitle" xml:space="preserve"><value>Titre du nouveau site</value></data>
|
||||||
|
<data name="templates.newalias" xml:space="preserve"><value>Alias du nouveau site</value></data>
|
||||||
|
<data name="templates.options" xml:space="preserve"><value>Options de capture</value></data>
|
||||||
|
<data name="templates.opt.libraries" xml:space="preserve"><value>Bibliotheques</value></data>
|
||||||
|
<data name="templates.opt.folders" xml:space="preserve"><value>Dossiers</value></data>
|
||||||
|
<data name="templates.opt.permissions" xml:space="preserve"><value>Groupes de permissions</value></data>
|
||||||
|
<data name="templates.opt.logo" xml:space="preserve"><value>Logo du site</value></data>
|
||||||
|
<data name="templates.opt.settings" xml:space="preserve"><value>Parametres du site</value></data>
|
||||||
|
<data name="templates.empty" xml:space="preserve"><value>Aucun modele enregistre.</value></data>
|
||||||
|
<!-- Phase 4: Shared bulk operation strings -->
|
||||||
|
<data name="bulk.confirm.title" xml:space="preserve"><value>Confirmer l'operation</value></data>
|
||||||
|
<data name="bulk.confirm.proceed" xml:space="preserve"><value>Continuer</value></data>
|
||||||
|
<data name="bulk.confirm.cancel" xml:space="preserve"><value>Annuler</value></data>
|
||||||
|
<data name="bulk.confirm.message" xml:space="preserve"><value>{0} — Continuer ?</value></data>
|
||||||
|
<data name="bulk.result.success" xml:space="preserve"><value>Termine : {0} reussis, {1} echoues</value></data>
|
||||||
|
<data name="bulk.result.allfailed" xml:space="preserve"><value>Les {0} elements ont echoue.</value></data>
|
||||||
|
<data name="bulk.result.allsuccess" xml:space="preserve"><value>Les {0} elements ont ete traites avec succes.</value></data>
|
||||||
|
<data name="bulk.exportfailed" xml:space="preserve"><value>Exporter les elements echoues</value></data>
|
||||||
|
<data name="bulk.retryfailed" xml:space="preserve"><value>Reessayer les echecs</value></data>
|
||||||
|
<data name="bulk.validation.invalid" xml:space="preserve"><value>{0} lignes contiennent des erreurs. Corrigez et reimportez.</value></data>
|
||||||
|
<data name="bulk.csvimport.title" xml:space="preserve"><value>Selectionner un fichier CSV</value></data>
|
||||||
|
<data name="bulk.csvimport.filter" xml:space="preserve"><value>Fichiers CSV (*.csv)|*.csv</value></data>
|
||||||
|
<!-- Phase 4: Folder browser dialog -->
|
||||||
|
<data name="folderbrowser.title" xml:space="preserve"><value>Selectionner un dossier</value></data>
|
||||||
|
<data name="folderbrowser.loading" xml:space="preserve"><value>Chargement de l'arborescence...</value></data>
|
||||||
|
<data name="folderbrowser.select" xml:space="preserve"><value>Selectionner</value></data>
|
||||||
|
<data name="folderbrowser.cancel" xml:space="preserve"><value>Annuler</value></data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -221,4 +221,87 @@
|
|||||||
<data name="ph.dup.lib" xml:space="preserve"><value>All (leave empty)</value></data>
|
<data name="ph.dup.lib" xml:space="preserve"><value>All (leave empty)</value></data>
|
||||||
<data name="btn.run.scan" xml:space="preserve"><value>Run Scan</value></data>
|
<data name="btn.run.scan" xml:space="preserve"><value>Run Scan</value></data>
|
||||||
<data name="btn.open.results" xml:space="preserve"><value>Open Results</value></data>
|
<data name="btn.open.results" xml:space="preserve"><value>Open Results</value></data>
|
||||||
|
<!-- Phase 4: Tab headers -->
|
||||||
|
<data name="tab.transfer" xml:space="preserve"><value>Transfer</value></data>
|
||||||
|
<data name="tab.bulkMembers" xml:space="preserve"><value>Bulk Members</value></data>
|
||||||
|
<data name="tab.bulkSites" xml:space="preserve"><value>Bulk Sites</value></data>
|
||||||
|
<data name="tab.folderStructure" xml:space="preserve"><value>Folder Structure</value></data>
|
||||||
|
<!-- Phase 4: Transfer tab -->
|
||||||
|
<data name="transfer.sourcesite" xml:space="preserve"><value>Source Site</value></data>
|
||||||
|
<data name="transfer.destsite" xml:space="preserve"><value>Destination Site</value></data>
|
||||||
|
<data name="transfer.sourcelibrary" xml:space="preserve"><value>Source Library</value></data>
|
||||||
|
<data name="transfer.destlibrary" xml:space="preserve"><value>Destination Library</value></data>
|
||||||
|
<data name="transfer.sourcefolder" xml:space="preserve"><value>Source Folder</value></data>
|
||||||
|
<data name="transfer.destfolder" xml:space="preserve"><value>Destination Folder</value></data>
|
||||||
|
<data name="transfer.mode" xml:space="preserve"><value>Transfer Mode</value></data>
|
||||||
|
<data name="transfer.mode.copy" xml:space="preserve"><value>Copy</value></data>
|
||||||
|
<data name="transfer.mode.move" xml:space="preserve"><value>Move</value></data>
|
||||||
|
<data name="transfer.conflict" xml:space="preserve"><value>Conflict Policy</value></data>
|
||||||
|
<data name="transfer.conflict.skip" xml:space="preserve"><value>Skip</value></data>
|
||||||
|
<data name="transfer.conflict.overwrite" xml:space="preserve"><value>Overwrite</value></data>
|
||||||
|
<data name="transfer.conflict.rename" xml:space="preserve"><value>Rename (append suffix)</value></data>
|
||||||
|
<data name="transfer.browse" xml:space="preserve"><value>Browse...</value></data>
|
||||||
|
<data name="transfer.start" xml:space="preserve"><value>Start Transfer</value></data>
|
||||||
|
<data name="transfer.nofiles" xml:space="preserve"><value>No files found to transfer.</value></data>
|
||||||
|
<!-- Phase 4: Bulk Members tab -->
|
||||||
|
<data name="bulkmembers.import" xml:space="preserve"><value>Import CSV</value></data>
|
||||||
|
<data name="bulkmembers.example" xml:space="preserve"><value>Load Example</value></data>
|
||||||
|
<data name="bulkmembers.execute" xml:space="preserve"><value>Add Members</value></data>
|
||||||
|
<data name="bulkmembers.preview" xml:space="preserve"><value>Preview ({0} rows, {1} valid, {2} invalid)</value></data>
|
||||||
|
<data name="bulkmembers.groupname" xml:space="preserve"><value>Group Name</value></data>
|
||||||
|
<data name="bulkmembers.groupurl" xml:space="preserve"><value>Group URL</value></data>
|
||||||
|
<data name="bulkmembers.email" xml:space="preserve"><value>Email</value></data>
|
||||||
|
<data name="bulkmembers.role" xml:space="preserve"><value>Role</value></data>
|
||||||
|
<!-- Phase 4: Bulk Sites tab -->
|
||||||
|
<data name="bulksites.import" xml:space="preserve"><value>Import CSV</value></data>
|
||||||
|
<data name="bulksites.example" xml:space="preserve"><value>Load Example</value></data>
|
||||||
|
<data name="bulksites.execute" xml:space="preserve"><value>Create Sites</value></data>
|
||||||
|
<data name="bulksites.preview" xml:space="preserve"><value>Preview ({0} rows, {1} valid, {2} invalid)</value></data>
|
||||||
|
<data name="bulksites.name" xml:space="preserve"><value>Name</value></data>
|
||||||
|
<data name="bulksites.alias" xml:space="preserve"><value>Alias</value></data>
|
||||||
|
<data name="bulksites.type" xml:space="preserve"><value>Type</value></data>
|
||||||
|
<data name="bulksites.owners" xml:space="preserve"><value>Owners</value></data>
|
||||||
|
<data name="bulksites.members" xml:space="preserve"><value>Members</value></data>
|
||||||
|
<!-- Phase 4: Folder Structure tab -->
|
||||||
|
<data name="folderstruct.import" xml:space="preserve"><value>Import CSV</value></data>
|
||||||
|
<data name="folderstruct.example" xml:space="preserve"><value>Load Example</value></data>
|
||||||
|
<data name="folderstruct.execute" xml:space="preserve"><value>Create Folders</value></data>
|
||||||
|
<data name="folderstruct.preview" xml:space="preserve"><value>Preview ({0} folders to create)</value></data>
|
||||||
|
<data name="folderstruct.library" xml:space="preserve"><value>Target Library</value></data>
|
||||||
|
<data name="folderstruct.siteurl" xml:space="preserve"><value>Site URL</value></data>
|
||||||
|
<!-- Phase 4: Templates tab -->
|
||||||
|
<data name="templates.list" xml:space="preserve"><value>Saved Templates</value></data>
|
||||||
|
<data name="templates.capture" xml:space="preserve"><value>Capture Template</value></data>
|
||||||
|
<data name="templates.apply" xml:space="preserve"><value>Apply Template</value></data>
|
||||||
|
<data name="templates.rename" xml:space="preserve"><value>Rename</value></data>
|
||||||
|
<data name="templates.delete" xml:space="preserve"><value>Delete</value></data>
|
||||||
|
<data name="templates.siteurl" xml:space="preserve"><value>Source Site URL</value></data>
|
||||||
|
<data name="templates.name" xml:space="preserve"><value>Template Name</value></data>
|
||||||
|
<data name="templates.newtitle" xml:space="preserve"><value>New Site Title</value></data>
|
||||||
|
<data name="templates.newalias" xml:space="preserve"><value>New Site Alias</value></data>
|
||||||
|
<data name="templates.options" xml:space="preserve"><value>Capture Options</value></data>
|
||||||
|
<data name="templates.opt.libraries" xml:space="preserve"><value>Libraries</value></data>
|
||||||
|
<data name="templates.opt.folders" xml:space="preserve"><value>Folders</value></data>
|
||||||
|
<data name="templates.opt.permissions" xml:space="preserve"><value>Permission Groups</value></data>
|
||||||
|
<data name="templates.opt.logo" xml:space="preserve"><value>Site Logo</value></data>
|
||||||
|
<data name="templates.opt.settings" xml:space="preserve"><value>Site Settings</value></data>
|
||||||
|
<data name="templates.empty" xml:space="preserve"><value>No templates saved yet.</value></data>
|
||||||
|
<!-- Phase 4: Shared bulk operation strings -->
|
||||||
|
<data name="bulk.confirm.title" xml:space="preserve"><value>Confirm Operation</value></data>
|
||||||
|
<data name="bulk.confirm.proceed" xml:space="preserve"><value>Proceed</value></data>
|
||||||
|
<data name="bulk.confirm.cancel" xml:space="preserve"><value>Cancel</value></data>
|
||||||
|
<data name="bulk.confirm.message" xml:space="preserve"><value>{0} — Proceed?</value></data>
|
||||||
|
<data name="bulk.result.success" xml:space="preserve"><value>Completed: {0} succeeded, {1} failed</value></data>
|
||||||
|
<data name="bulk.result.allfailed" xml:space="preserve"><value>All {0} items failed.</value></data>
|
||||||
|
<data name="bulk.result.allsuccess" xml:space="preserve"><value>All {0} items completed successfully.</value></data>
|
||||||
|
<data name="bulk.exportfailed" xml:space="preserve"><value>Export Failed Items</value></data>
|
||||||
|
<data name="bulk.retryfailed" xml:space="preserve"><value>Retry Failed</value></data>
|
||||||
|
<data name="bulk.validation.invalid" xml:space="preserve"><value>{0} rows have validation errors. Fix and re-import.</value></data>
|
||||||
|
<data name="bulk.csvimport.title" xml:space="preserve"><value>Select CSV File</value></data>
|
||||||
|
<data name="bulk.csvimport.filter" xml:space="preserve"><value>CSV Files (*.csv)|*.csv</value></data>
|
||||||
|
<!-- Phase 4: Folder browser dialog -->
|
||||||
|
<data name="folderbrowser.title" xml:space="preserve"><value>Select Folder</value></data>
|
||||||
|
<data name="folderbrowser.loading" xml:space="preserve"><value>Loading folder tree...</value></data>
|
||||||
|
<data name="folderbrowser.select" xml:space="preserve"><value>Select</value></data>
|
||||||
|
<data name="folderbrowser.cancel" xml:space="preserve"><value>Cancel</value></data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
8
SharepointToolbox/Resources/bulk_add_members.csv
Normal file
8
SharepointToolbox/Resources/bulk_add_members.csv
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
GroupName,GroupUrl,Email,Role
|
||||||
|
Marketing Team,https://contoso.sharepoint.com/sites/Marketing,user1@contoso.com,Member
|
||||||
|
Marketing Team,https://contoso.sharepoint.com/sites/Marketing,manager@contoso.com,Owner
|
||||||
|
HR Team,https://contoso.sharepoint.com/sites/HR,hr-admin@contoso.com,Owner
|
||||||
|
HR Team,https://contoso.sharepoint.com/sites/HR,recruiter@contoso.com,Member
|
||||||
|
HR Team,https://contoso.sharepoint.com/sites/HR,analyst@contoso.com,Member
|
||||||
|
IT Support,https://contoso.sharepoint.com/sites/IT,sysadmin@contoso.com,Owner
|
||||||
|
IT Support,https://contoso.sharepoint.com/sites/IT,helpdesk@contoso.com,Member
|
||||||
|
6
SharepointToolbox/Resources/bulk_create_sites.csv
Normal file
6
SharepointToolbox/Resources/bulk_create_sites.csv
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name;Alias;Type;Template;Owners;Members
|
||||||
|
Projet Alpha;projet-alpha;Team;;admin@contoso.com;user1@contoso.com, user2@contoso.com
|
||||||
|
Projet Beta;projet-beta;Team;;admin@contoso.com;user3@contoso.com, user4@contoso.com
|
||||||
|
Communication RH;comm-rh;Communication;;rh-admin@contoso.com;manager1@contoso.com, manager2@contoso.com
|
||||||
|
Equipe Marketing;equipe-marketing;Team;;marketing-lead@contoso.com;designer@contoso.com, redacteur@contoso.com
|
||||||
|
Portail Intranet;portail-intranet;Communication;;it-admin@contoso.com;
|
||||||
|
20
SharepointToolbox/Resources/folder_structure.csv
Normal file
20
SharepointToolbox/Resources/folder_structure.csv
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Level1;Level2;Level3;Level4
|
||||||
|
Administration;;;
|
||||||
|
Administration;Comptabilite;;
|
||||||
|
Administration;Comptabilite;Factures;
|
||||||
|
Administration;Comptabilite;Bilans;
|
||||||
|
Administration;Ressources Humaines;;
|
||||||
|
Administration;Ressources Humaines;Contrats;
|
||||||
|
Administration;Ressources Humaines;Fiches de paie;
|
||||||
|
Projets;;;
|
||||||
|
Projets;Projet Alpha;;
|
||||||
|
Projets;Projet Alpha;Documents;
|
||||||
|
Projets;Projet Alpha;Livrables;
|
||||||
|
Projets;Projet Beta;;
|
||||||
|
Projets;Projet Beta;Documents;
|
||||||
|
Communication;;;
|
||||||
|
Communication;Interne;;
|
||||||
|
Communication;Interne;Notes de service;
|
||||||
|
Communication;Externe;;
|
||||||
|
Communication;Externe;Communiques de presse;
|
||||||
|
Communication;Externe;Newsletter;
|
||||||
|
@@ -25,6 +25,12 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Resources\bulk_add_members.csv" />
|
||||||
|
<EmbeddedResource Include="Resources\bulk_create_sites.csv" />
|
||||||
|
<EmbeddedResource Include="Resources\folder_structure.csv" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="CsvHelper" Version="33.1.0" />
|
<PackageReference Include="CsvHelper" Version="33.1.0" />
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<Window x:Class="SharepointToolbox.Views.Dialogs.ConfirmBulkOperationDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:loc="clr-namespace:SharepointToolbox.Localization"
|
||||||
|
Title="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[bulk.confirm.title]}"
|
||||||
|
Width="450" Height="220" WindowStartupLocation="CenterOwner"
|
||||||
|
ResizeMode="NoResize">
|
||||||
|
<Grid Margin="20">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock x:Name="MessageText" Grid.Row="0"
|
||||||
|
TextWrapping="Wrap" FontSize="14"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Right" Margin="0,20,0,0">
|
||||||
|
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[bulk.confirm.cancel]}"
|
||||||
|
Width="100" Margin="0,0,10,0" IsCancel="True"
|
||||||
|
Click="Cancel_Click" />
|
||||||
|
<Button x:Name="ProceedButton"
|
||||||
|
Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[bulk.confirm.proceed]}"
|
||||||
|
Width="100" IsDefault="True"
|
||||||
|
Click="Proceed_Click" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace SharepointToolbox.Views.Dialogs;
|
||||||
|
|
||||||
|
public partial class ConfirmBulkOperationDialog : Window
|
||||||
|
{
|
||||||
|
public bool IsConfirmed { get; private set; }
|
||||||
|
|
||||||
|
public ConfirmBulkOperationDialog(string message)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
MessageText.Text = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Proceed_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
IsConfirmed = true;
|
||||||
|
DialogResult = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
IsConfirmed = false;
|
||||||
|
DialogResult = false;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
28
SharepointToolbox/Views/Dialogs/FolderBrowserDialog.xaml
Normal file
28
SharepointToolbox/Views/Dialogs/FolderBrowserDialog.xaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<Window x:Class="SharepointToolbox.Views.Dialogs.FolderBrowserDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:loc="clr-namespace:SharepointToolbox.Localization"
|
||||||
|
Title="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[folderbrowser.title]}"
|
||||||
|
Width="400" Height="500" WindowStartupLocation="CenterOwner"
|
||||||
|
ResizeMode="CanResizeWithGrip">
|
||||||
|
<DockPanel Margin="10">
|
||||||
|
<!-- Status -->
|
||||||
|
<TextBlock x:Name="StatusText" DockPanel.Dock="Top" Margin="0,0,0,10"
|
||||||
|
Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[folderbrowser.loading]}" />
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||||
|
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[folderbrowser.cancel]}"
|
||||||
|
Width="80" Margin="0,0,10,0" IsCancel="True"
|
||||||
|
Click="Cancel_Click" />
|
||||||
|
<Button x:Name="SelectButton"
|
||||||
|
Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[folderbrowser.select]}"
|
||||||
|
Width="80" IsDefault="True" IsEnabled="False"
|
||||||
|
Click="Select_Click" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Tree -->
|
||||||
|
<TreeView x:Name="FolderTree" SelectedItemChanged="FolderTree_SelectedItemChanged" />
|
||||||
|
</DockPanel>
|
||||||
|
</Window>
|
||||||
125
SharepointToolbox/Views/Dialogs/FolderBrowserDialog.xaml.cs
Normal file
125
SharepointToolbox/Views/Dialogs/FolderBrowserDialog.xaml.cs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using Microsoft.SharePoint.Client;
|
||||||
|
using SharepointToolbox.Core.Helpers;
|
||||||
|
|
||||||
|
namespace SharepointToolbox.Views.Dialogs;
|
||||||
|
|
||||||
|
public partial class FolderBrowserDialog : Window
|
||||||
|
{
|
||||||
|
private readonly ClientContext _ctx;
|
||||||
|
public string SelectedLibrary { get; private set; } = string.Empty;
|
||||||
|
public string SelectedFolderPath { get; private set; } = string.Empty;
|
||||||
|
|
||||||
|
public FolderBrowserDialog(ClientContext ctx)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
_ctx = ctx;
|
||||||
|
Loaded += OnLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Load libraries
|
||||||
|
var web = _ctx.Web;
|
||||||
|
var lists = _ctx.LoadQuery(web.Lists
|
||||||
|
.Include(l => l.Title, l => l.Hidden, l => l.BaseType, l => l.RootFolder)
|
||||||
|
.Where(l => !l.Hidden && l.BaseType == BaseType.DocumentLibrary));
|
||||||
|
var progress = new Progress<Core.Models.OperationProgress>();
|
||||||
|
await ExecuteQueryRetryHelper.ExecuteQueryRetryAsync(_ctx, progress, CancellationToken.None);
|
||||||
|
|
||||||
|
foreach (var list in lists)
|
||||||
|
{
|
||||||
|
var libNode = new TreeViewItem
|
||||||
|
{
|
||||||
|
Header = list.Title,
|
||||||
|
Tag = new FolderNodeInfo(list.Title, string.Empty),
|
||||||
|
};
|
||||||
|
// Add dummy child for expand arrow
|
||||||
|
libNode.Items.Add(new TreeViewItem { Header = "Loading..." });
|
||||||
|
libNode.Expanded += LibNode_Expanded;
|
||||||
|
FolderTree.Items.Add(libNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusText.Text = $"{FolderTree.Items.Count} libraries loaded.";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatusText.Text = $"Error: {ex.Message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void LibNode_Expanded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not TreeViewItem node || node.Tag is not FolderNodeInfo info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Only load children once
|
||||||
|
if (node.Items.Count == 1 && node.Items[0] is TreeViewItem dummy && dummy.Header?.ToString() == "Loading...")
|
||||||
|
{
|
||||||
|
node.Items.Clear();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var folderUrl = string.IsNullOrEmpty(info.FolderPath)
|
||||||
|
? GetLibraryRootUrl(info.LibraryTitle)
|
||||||
|
: info.FolderPath;
|
||||||
|
|
||||||
|
var folder = _ctx.Web.GetFolderByServerRelativeUrl(folderUrl);
|
||||||
|
_ctx.Load(folder, f => f.Folders.Include(sf => sf.Name, sf => sf.ServerRelativeUrl));
|
||||||
|
var progress = new Progress<Core.Models.OperationProgress>();
|
||||||
|
await ExecuteQueryRetryHelper.ExecuteQueryRetryAsync(_ctx, progress, CancellationToken.None);
|
||||||
|
|
||||||
|
foreach (var subFolder in folder.Folders)
|
||||||
|
{
|
||||||
|
if (subFolder.Name.StartsWith("_") || subFolder.Name == "Forms")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var childNode = new TreeViewItem
|
||||||
|
{
|
||||||
|
Header = subFolder.Name,
|
||||||
|
Tag = new FolderNodeInfo(info.LibraryTitle, subFolder.ServerRelativeUrl),
|
||||||
|
};
|
||||||
|
childNode.Items.Add(new TreeViewItem { Header = "Loading..." });
|
||||||
|
childNode.Expanded += LibNode_Expanded;
|
||||||
|
node.Items.Add(childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
node.Items.Add(new TreeViewItem { Header = $"Error: {ex.Message}" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetLibraryRootUrl(string libraryTitle)
|
||||||
|
{
|
||||||
|
var uri = new Uri(_ctx.Url);
|
||||||
|
return $"{uri.AbsolutePath.TrimEnd('/')}/{libraryTitle}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FolderTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||||
|
{
|
||||||
|
if (e.NewValue is TreeViewItem node && node.Tag is FolderNodeInfo info)
|
||||||
|
{
|
||||||
|
SelectedLibrary = info.LibraryTitle;
|
||||||
|
SelectedFolderPath = info.FolderPath;
|
||||||
|
SelectButton.IsEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Select_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult = false;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private record FolderNodeInfo(string LibraryTitle, string FolderPath);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user