### Running Scripts with npm Source: https://github.com/eon-dev1/web-xforge/blob/master/scripts/db_tools/README.md Instructions for running project scripts, including installing dependencies using npm and executing scripts from the db_tools directory. ```bash npm install # or npm ci ./script-name ``` -------------------------------- ### Install VirtualBox Guest Additions Source: https://github.com/eon-dev1/web-xforge/blob/master/deploy/vagrant/sfdev/base/instructions.md Installs VirtualBox guest additions in the guest machine. Requires build-essential and the guest additions run script. Assumes the script is mounted via the CD image. ```shell sudo apt update && sudo apt install --assume-yes build-essential && sudo /media/vagrant/VBox*/VBoxLinuxAdditions.run ``` -------------------------------- ### Package and Test Base Box Source: https://github.com/eon-dev1/web-xforge/blob/master/deploy/vagrant/sfdev/base/instructions.md Packages the current VirtualBox VM into a .box file, generates its SHA256 checksum, creates a test Vagrantfile to use the new box, and starts the test VM. Requires Vagrant and VirtualBox to be installed. ```shell export BOX="sfdev" && export VERSION="1.2.0" && date && vagrant package --base ${BOX}-base --output ${BOX}-${VERSION}.box && date && ls -lh ${BOX}-${VERSION}.box && sha256sum ${BOX}-${VERSION}.box | tee --append "${BOX}".json && date && mkdir test && tee test/Vagrantfile < User HostName LocalForward localhost: Host * ServerAliveInterval 60 ``` -------------------------------- ### Install Playwright Dependencies Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/e2e/README.md Installs necessary Playwright dependencies for running end-to-end tests. This typically involves system-level packages and Playwright's own binaries. ```bash sudo apt install libavif-bin cd src/SIL.XForge.Scripture/ClientApp/e2e npx playwright install ``` -------------------------------- ### Angular CLI Unit Tests Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/README.md Executes unit tests for the Angular application using Karma. Requires Angular CLI and Karma setup. ```bash ng test ``` -------------------------------- ### Run End-to-End Tests Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/e2e/README.md Executes the end-to-end tests using the Deno runtime. Assumes all dependencies and setup are completed. ```bash cd src/SIL.XForge.Scripture/ClientApp/e2e ./e2e.mts ``` -------------------------------- ### Displaying Help Instructions Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html This code iterates through 'helpInstructions' to display relevant help text. It conditionally shows plain text, specific formatted text, or an email link for reporting issues based on the instruction ID. ```html @for (i of helpInstructions | async; track i) { @if (i.id == null) {{{ i.text }}} @else if (i.id === 1) { {{ i.text }} } @else if (i.id === 3) { [{{ issueEmail }}](mailto:{{ issueEmail }}) } } ``` -------------------------------- ### Drag and Drop File Instructions Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/chapter-audio-dialog/chapter-audio-dialog.component.html Provides user instructions for file uploading via drag and drop or browsing, using translated text. ```html {{ t("drag_and_drop_files") }}, {{ t("drag_and_drop_or_browse") }} {{ t("browse_files") }} ``` -------------------------------- ### View Questions by Book and Chapter Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking-overview/checking-overview.component.html Displays questions organized by book and chapter. Shows the number of questions and answers for each, along with audio file indicators and archive options. Conditional rendering based on edit permissions and content availability. ```html @if (canEditQuestion) { @for (text of texts; track text.bookNum) { @if (bookQuestionCount(text) > 0 || bookHasChapterAudio(text)) { {{ getBookName(text) }} {{ questionCountLabel(bookQuestionCount(text)) }} {{ answerCountLabel(bookAnswerCount(text)) }} @if (bookQuestionCount(text) > 0) { archive } @for (chapter of text.chapters; track chapter.number) { @if (questionCount(text.bookNum, chapter.number) > 0 || chapter.hasAudio) { {{ getBookName(text) + " " + chapter?.number }} @if (chapter.hasAudio) { audio_file } {{ questionCountLabel(questionCount(text.bookNum, chapter.number)) }} {{ answerCountLabel(chapterAnswerCount(text.bookNum, chapter.number)) }} @if (questionCount(text.bookNum, chapter.number) > 0) { archive } @for ( questionDoc of getQuestionDocs(getTextDocIdType(text.bookNum, chapter.number)); track questionDoc.data!.dataId ) { edit v{{ questionReference(questionDoc.data?.verseRef) }} -  @if (questionDoc.data?.audioUrl) { audio_file } {{ questionDoc.data?.text ?? "" }} {{ answerCountLabel(questionDoc.getAnswers().length) }} archive } } } } } } @else { @for (text of texts; track text.bookNum) { @if (bookQuestionCount(text) > 0) { {{ getBookName(text) }} } } } ``` -------------------------------- ### Project-Level Actions and Navigation Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking/checking.component.html Provides project-level actions such as adding a new question and viewing the question list. It also includes navigation buttons for moving backward and forward. ```html @if (projectDoc) { @if (canCreateQuestions) { post_add post_add {{ t("add_question") }} } @if (!isQuestionListPermanent) { keyboard_arrow_up {{ t("view_questions") }} } } ``` -------------------------------- ### Angular CLI Help Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/README.md Displays help information for the Angular CLI and its commands. Useful for exploring available options. ```bash ng help ``` -------------------------------- ### Reference Project Overview Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Iterates through reference projects and displays their names, with a placeholder for null projects. ```html @for (project of trainingSources; track $index) { @if (project == null) { } @else { {{ project.name }} } } ``` -------------------------------- ### Conditional Downtime Notice Display Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/shared/global-notices/global-notices.component.html This snippet uses a JavaScript conditional statement to determine whether to display the downtime notice. It includes placeholders for localized text and dynamic data like duration and start time, along with a 'learn more' link and a close action. ```html @if (showDowntimeNotice) { {{ t("upcoming_maintenance", { duration, startTime: i18n.formatDate(upcomingDowntime.start, { showTimeZone: true }) }) }} {{ t("learn_more") }} close } ``` -------------------------------- ### User Authentication and Profile Display Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html Illustrates how to check the login status of a user and display their profile information. It also includes actions related to user roles like system admin and serval admin. ```html @if (isLoggedIn | async) { ![](/assets/images/sf.svg) } @else { [![](/assets/images/sf.svg) ](/)} {{ currentUser?.displayName }} @if (isSystemAdmin) { admin_panel_settings {{ t("system_administration") }} } @if (isServalAdmin) { tune {{ t("serval_administration") }} } @if (isSystemAdmin) { pending_actions {{ t("hangfire_dashboard") }} } @if (canChangePassword) { vpn_key {{ t("change_password") }} } @if (canInstallOnDevice$ | async) { install_mobile {{ t("install_on_device") }} } logout {{ t("log_out") }} {{ t("logged_in_as") }} ``` -------------------------------- ### Angular CLI Build Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/README.md Builds the Angular application for deployment. Use the --prod flag for a production-optimized build. Output is stored in the dist/ directory. ```bash ng build ng build --prod ``` -------------------------------- ### Source Project Overview Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Iterates through source projects and displays their names, with a placeholder for null projects. ```html @for (project of draftingSources; track $index) { @if (project == null) { } @else { {{ project.name }} } } ``` -------------------------------- ### Conditional Rendering Logic Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.html Demonstrates conditional rendering based on various boolean flags and user settings. Includes icons for source and suggestions, and handles sharing and multi-viewer states. ```html @if (showSource || suggestionsSettingsEnabled) { @if (showSource) { swap_horiz } @if (suggestionsSettingsEnabled) { settings } } @if (canShare) { } @if (showMultiViewers) { } ``` -------------------------------- ### File Upload and Import/Export Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking-overview/checking-overview.component.html Handles file uploads for importing questions and provides options to export questions. Includes conditional rendering based on the number of existing questions. ```html @if (canCreateQuestion) { @if (showImportButton) { file_upload {{ t("import") }} @if (allQuestionsCount > 0) { download {{ t("export") }} } } } ``` -------------------------------- ### Running Serval Build Report Source: https://github.com/eon-dev1/web-xforge/blob/master/tools/ServalBuildReport/README.md Commands to run the Serval Build Report tool for Production and QA environments. ```sh dotnet run prod dotnet run qa ``` -------------------------------- ### Internationalization (i18n) with Transloco Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html Shows how to use the Transloco library for internationalization, including translating strings and handling dynamic parameters in translations. It also demonstrates checking for available locales. ```html @for (locale of i18n.locales; track locale.canonicalTag) { check {{ locale.localName }}} } help help {{ t("help") }} campaign {{ t("announcements") }} forum {{ t("community_support") }} mail {{ t("report_issue") }} {{ t("report_issue_email", { email: issueEmail }) }} [copyright {{ t("open_source_licenses") }}](/3rdpartylicenses.txt) {{ t("product_version", { version: version + featureFlags.versionSuffix }) }} {{ "my_projects.my_projects" | transloco }} {{ t("system_administration") }} {{ t("serval_administration") }} {{ t("hangfire_dashboard") }} {{ t("change_password") }} {{ t("install_on_device") }} {{ t("log_out") }} {{ t("online") }} {{ t("offline") }} {{ t("update_is_available") }} {{ t("refresh") }} {{ t("scripture_checking_not_available") }} ``` -------------------------------- ### Advanced Settings Configuration Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation-steps/draft-generation-steps.component.html Conditionally displays advanced settings for fast training and echo usage, including warnings if enabled. This section is only visible if the developer tools feature flag is enabled. ```html @if (featureFlags.showDeveloperTools.enabled) { {{ t("configure_advanced_settings_header") }} {{ t("configure_advanced_settings_title") }} =============================================== {{ t("fast_training") }} @if (fastTraining) { {{ t("fast_training_warning") }} } {{ t("use_echo") }} @if (useEcho) { {{ t("use_echo_warning") }} } ``` -------------------------------- ### Overview Reference Section Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Section for the overview of reference projects, including the reference language display name. ```html ### {{ t("overview_reference") }} {{ parentheses(referenceLanguageDisplayName) }} ``` -------------------------------- ### Book Selection for Training Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation-steps/draft-generation-steps.component.html Manages the selection of books for training, including handling unusable source books, reference books, and displaying relevant error messages or informational text. ```html {{ t("choose_books_for_training_header") }} {{ t("choose_books_for_training_title") }} ============================================== {{ t("translated_books") }} ---------------------------- @if (unusableTrainingSourceBooks.length) { @if (expandUnusableTrainingBooks) { {{ bookNames(unusableTrainingSourceBooks) }} } } {{ t("reference_books") }} --------------------------- @for (source of trainingSources; track source) { {{ projectLabel(source) }} @if (selectableTrainingBooksByProj(source.projectRef).length === 0) { {{ t("training_books_will_appear") }} } @else { } } @if (!isTrainingOptional && selectableTrainingBooksByProj(activatedProject.projectId).length === 0) { {{ t("choose_books_for_training_no_books_error") }} } @else if (!translatedBooksSelectedInTrainingSources) { {{ t("translated_book_selected_no_training_pair") }} } @else if (showBookSelectionError) { {{ t("choose_books_for_training_error") }} } @if (translatedBooksWithNoSource.length > 0) { {{ t("source_books_missing") }} } ``` -------------------------------- ### Summary of Selected Books Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation-steps/draft-generation-steps.component.html Displays a summary of the selected training and translation books. For training books, it lists the source and target languages and names. For translation books, it shows a formatted string of selected books. ```html {{ t("summary_header") }} {{ t("summary_title") }} ========================= {{ t("summary_training_title") }} ----------------------------------- @if (selectedTrainingBooksCollapsed().length === 0) { {{ t("no_training_books") }} } @else { {{ t("summary_training") }} {{ t("training_books") }} {{ i18n.enumerateList(element.ranges) }} {{ i18n.getLanguageDisplayName(trainingSources[0].writingSystem.tag) }} {{ element.sourceName }} {{ i18n.getLanguageDisplayName(trainingTargets[0].writingSystem.tag) }} {{ trainingTargets[0].shortName }} } {{ t("summary_translate") }} {{ selectedTranslateBooksAsString() }} ``` -------------------------------- ### Training Language Model Section Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Section header for the training language model. ```html {{ t("training_language_model") }} ``` -------------------------------- ### Iterating Through Chapters Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/shared/book-chapter-chooser/book-chapter-chooser.component.html This snippet shows how to iterate through a list of chapters and display each chapter. ```html @for (c of chapters; track c) { {{ c }} } ``` -------------------------------- ### Translated Project Overview Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Iterates through translated projects and displays their names. ```html @for (project of trainingTargets; track $index) { {{ project.name }} } ``` -------------------------------- ### Import from Spreadsheet with Verse Numbering Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.html This snippet demonstrates importing from a spreadsheet, specifically handling verse numbers. It iterates through a range of verse numbers and displays a question for each, along with reference information. ```html {{ t("import_from_spreadsheet") }} 1. {{ csvInstructions[0] }} @for (verseNumber of [1, 2]; track verseNumber) { } Reference Question 1JN 1:{{ verseNumber }} {{ t("question_for_verse", { number: verseNumber }) }} ``` -------------------------------- ### Training Files Description Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Displays a description for training files, interpolating source and target language display names. ```html {{ t("training_files_description", { sourceLanguageDisplayName, targetLanguageDisplayName }) }} ``` -------------------------------- ### Iterating and Displaying Note Information Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/note-dialog/note-dialog.component.html Iterates through a list of notes (`notesToDisplay`) and displays assignment, reattached verse/text, edit/delete options, username, and creation date for each note. ```HTML @for (noteInfo of notesToDisplay; track noteInfo) { @if (noteInfo.assignment != null) { >{{ noteInfo.assignment }} } @if (noteInfo.reattachedVerse != null) { {{ noteInfo.reattachedVerse }} } @if (noteInfo.reattachedText != null) { } @if (noteInfo.editable) { edit delete } {{ noteInfo.userName }} {{ noteInfo.dateCreated }} } ``` -------------------------------- ### Overview Source Section Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Section for the overview of source projects, including the source language display name. ```html ### {{ t("overview_source") }} {{ parentheses(sourceLanguageDisplayName) }} ``` -------------------------------- ### Audio and Navigation Controls Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking/checking.component.html Renders audio playback controls (play/stop) if chapter audio is available, an audio file icon if scripture audio can be created, and a share icon if sharing is enabled. It also includes navigation elements for moving between chapters. ```html @if (chapterHasAudio) { {{ isAudioPlaying() ? "stop" : "play_circle_outline" }} } @if (canCreateScriptureAudio) { audio_file } @if (canShare) { } chevron\_{{ i18n.backwardDirectionWord }}{{ t("previous") }} {{ t("next") }}chevron\_{{ i18n.forwardDirectionWord }} chevron\_{{ i18n.backwardDirectionWord }} chevron\_{{ i18n.forwardDirectionWord }} ``` -------------------------------- ### Add New Question Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking-overview/checking-overview.component.html Allows users to add new questions to the project. This functionality is available when the user has permission to create questions and data is not currently loading. ```html @if (canCreateQuestion) { @if (!isLoadingData) { post_add {{ t("add_question") }} post_add } ``` -------------------------------- ### Conditional UI Rendering Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html Demonstrates conditional rendering of UI elements based on application state and user roles. This includes showing site admin options, menu items, login/logout states, project details, and developer tools. ```html @if (isLive && isSystemAdmin) { site admin } @if (!isDrawerPermanent && isProjectSelected) { menu } @if (isLoggedIn | async) { ![](/assets/images/sf.svg) } @else { [![](/assets/images/sf.svg) ](/)} @if (isProjectSelected) { @if (isScreenTiny) { {{ selectedProjectDoc?.data?.shortName }} } @else { {{ selectedProjectDoc?.data?.name }} {{ selectedProjectDoc?.data?.shortName }} } } @if (isAppOnline) { translate } @for (locale of i18n.locales; track locale.canonicalTag) { check {{ locale.localName }} } help help {{ t("help") }} campaign {{ t("announcements") }} forum {{ t("community_support") }} mail {{ t("report_issue") }} {{ t("report_issue_email", { email: issueEmail }) }} [copyright {{ t("open_source_licenses") }}](/3rdpartylicenses.txt) {{ t("product_version", { version: version + featureFlags.versionSuffix }) }} @if (featureFlags.showDeveloperTools.enabled) { science Developer settings integration_instructions Developer diagnostics } @if (currentUser) { @if (showInstallIconOnAvatar$ | async) { install_mobile } @if (!isAppOnline) { cloud_off } } {{ t("logged_in_as") }} {{ currentUser?.displayName }} edit @if (isSystemAdmin) { admin_panel_settings {{ t("system_administration") }} } @if (isServalAdmin) { tune {{ t("serval_administration") }} } @if (isSystemAdmin) { pending_actions {{ t("hangfire_dashboard") }} } home {{ "my_projects.my_projects" | transloco }} @if (canChangePassword) { vpn_key {{ t("change_password") }} } @if (canInstallOnDevice$ | async) { install_mobile {{ t("install_on_device") }} } logout {{ t("log_out") }} @if (isAppOnline) { cloud {{ t("online") }} } @else { cloud_off {{ t("offline") }} } @if (hasUpdate) { {{ t("update_is_available") }} {{ t("refresh") }} } @if (isProjectSelected) { } @if (showCheckingDisabled) { {{ t("scripture_checking_not_available") }} } ``` -------------------------------- ### Conditional Rendering and Iteration for Suggestions Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/suggestions.component.html This snippet demonstrates conditional rendering based on a loading state and iterates through a list of suggestions, displaying the words and confidence percentage for each. It uses Angular-like template syntax. ```html @if (isLoading) { } @else { @for (suggestion of suggestions; track $index; let i = $index) { {{ suggestion.words.join(" ") }} {{ getPercentage(suggestion.confidence) }}% } } ``` -------------------------------- ### Reference Projects Section Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Section for reference projects, including a subtitle and expansion control. ```html {{ t("reference_projects") }} {{ referencesSubtitle }} {{ step === 2 ? "expand_less" : "expand_more" }} ``` -------------------------------- ### Book and Chapter Information Display Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/chapter-audio-dialog/chapter-audio-dialog.component.html Displays book name, chapter number, and a label for audio. Assumes 'bookName' is a function and 'chapter' is a variable. ```html {{ bookName(book) }} {{ chapter }} {{ t("audio") }} ``` -------------------------------- ### Select Project to Translate Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Section for selecting the project to translate, with an expansion control. ```html {{ t("select_project_to_translate") }} {{ step === 1 ? "expand_less" : "expand_more" }} ``` -------------------------------- ### Reference Project Selection Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Allows selection of reference projects, considering back-translation and displaying the source language if available. ```html {{ t("select_reference_project_considering_back_translation") }} @if (sourceLanguageDisplayName) { @for (portion of i18n.interpolateVariables("draft_sources.same_language_as_given_language"); track $index) { @if (portion.id === "sourceLanguageDisplayName") { **{{ sourceLanguageDisplayName }}** } @else { {{{ portion.text }}} } } } @else { {{ t("same_language_as_source") }} } ``` -------------------------------- ### Add Training Source Button Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Conditionally displays a button to add another reference project if allowed. ```html @if (allowAddingATrainingSource) { add {{ t("add_another_reference_project") }} } ``` -------------------------------- ### Navigation Buttons Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Renders 'Previous' and 'Next' buttons based on the current step in a multi-step process. ```html @if (step !== 1) { {{ t("previous") }} } @if (step !== 3) { {{ t("next") }} } ``` -------------------------------- ### Monitor System Changes Source: https://github.com/eon-dev1/web-xforge/blob/master/deploy/vagrant/sfdev/base/instructions.md Provides commands to monitor system configuration changes within the guest machine, useful for debugging or understanding the effects of updates and settings. ```shell gsettings list-recursively dconf dump / inotifywatch --verbose --recursive ~ ``` -------------------------------- ### Iterating and Displaying Book Options Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/shared/book-multi-select/book-multi-select.component.html This code iterates through a list of book options, displaying book names with internationalization. It includes a conditional rendering path for 'basicMode'. ```html @for (book of bookOptions; track book.bookId) { @if (!basicMode) { {{ "canon.book_names." + book.bookId | transloco }} } @else { {{ "canon.book_names." + book.bookId | transloco }} } } ``` -------------------------------- ### Handling Multiple Insights Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/lynx/insights/lynx-insight-overlay/lynx-insight-overlay.component.html This snippet shows the logic for when multiple insights are available but none are focused. It displays a header prompting the user to select an insight for details and then lists each insight's description. ```html @else if (insights.length > 1) { {{ t("multi_insight_header_select_for_details") }} ======================================================= @for (insight of insights; track insight.id) { {{ insight.description }} ========================= more_horiz } } ``` -------------------------------- ### Loading Message Display Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/shared/book-multi-select/book-multi-select.component.html This snippet shows how to display a loading message using internationalization when the content is not yet loaded. ```html @if (!loaded) { {{ t("loading_message") }} } ``` -------------------------------- ### Finalize Base Box Cleanup Source: https://github.com/eon-dev1/web-xforge/blob/master/deploy/vagrant/sfdev/base/instructions.md Cleans up the guest system by removing unused packages, clearing the package cache, removing SSH host keys, and zeroing out deleted files to free up disk space. Expects a 'No space left on device' error for the zeroing step. ```shell sudo apt-get update && sudo apt-get --assume-yes autoremove && sudo apt-get --assume-yes clean && sudo rm -v /etc/ssh/ssh_host_* cat /dev/zero > ~/zeros; sync; ls -lh ~/zeros; rm -v ~/zeros ``` -------------------------------- ### Draft Source Configuration Section Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Main section for configuring draft sources, including placeholders for source subtitles and expansion controls. ```html {{ t("configure_draft_sources") }} ==================================== {{ t("draft_source") }} {{ sourceSubtitle }} {{ step === 1 ? "expand_less" : "expand_more" }} ``` -------------------------------- ### Conditional Content Rendering (HTML) Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/scripture-chooser-dialog/scripture-chooser-dialog.component.html Demonstrates the use of a switch statement to conditionally render content based on the 'showing' variable. It iterates over book and chapter data, applying localization. ```html @switch (showing) { @case ("books") { close {{ t("choose_book") }} ============================= @for (book of otBooks; track book) { {{ i18n.localizeBook(book) }} } @for (book of ntBooks; track book) { {{ i18n.localizeBook(book) }} } } @case ("chapters") { navigate_before {{ t("choose_chapter") }} =========================================== {{ getBookName(selection.book) }} @for (chapter of chaptersOf(selection.book); track chapter) { {{ chapter }} } } @case ("verses") { navigate_before {{ t("choose_verse") }} ========================================= {{ getBookName(selection.book) }} {{ selection.chapter }} @for (verse of versesOf(selection.book, selection.chapter); track verse) { {{ verse }} } } @case ("rangeEnd") { close {{ t("choose_end_verse") }} {{ getBookName(data.rangeStart?.book) }} {{ data.rangeStart?.chapter }} @for ( verse of versesOf(data.rangeStart?.book, data.rangeStart?.chapter, data.rangeStart?.verseNum); track verse ) { {{ verse }} } } } ``` -------------------------------- ### Project Settings UI Logic Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/settings/settings.component.html This snippet demonstrates conditional rendering and data binding in an Angular template for project settings. It handles network status, loading states, project/resource fetching errors, translation suggestions based on source text, biblical terms display, pre-translation drafting settings, Serval configuration, community checking options, sharing settings with role descriptions, and project deletion logic with various cautionary states. ```html Project Settings

{{ t("settings") }}

@if (!isAppOnline) { {{ t("connect\_network\_to\_change\_settings") }} } {{ t("translate") }} @if (!isLoadingData && !isLoggedInToParatext && isAppOnline) { Paratext Logo {{ t("log\_in\_with\_paratext") }} } @if (mainSettingsLoaded) { {{ t("select\_project\_or\_resource") }} @if (projectLoadingFailed && resourceLoadingFailed) { {{ t("error\_fetching\_projects\_resources") }} } @else if (projectLoadingFailed && !resourceLoadingFailed) { {{ t("error\_fetching\_projects") }} } @else if (resourceLoadingFailed && !projectLoadingFailed) { {{ t("error\_fetching\_resources") }} } } @if (isBasedOnProjectSet) { {{ t("translation\_suggestions") }} } @else { {{ t("translation\_suggestions\_require\_source\_text") }} } {{ t("biblical\_terms") }} @if (biblicalTermsMessage) { {{ biblicalTermsMessage }} } @if (showPreTranslationSettings) { {{ t("pre\_translation\_drafting") }} @if (mainSettingsLoaded) { @if (showDraftGenerationSettingsMovedMessage) { @for (part of draftSettingsRelocatedMessage | async; track part) { @if (part.id == null) { {{{ part.text }}} } @else if (part.id === 1) { {{ part.text }} } } @if (showHighlightedDraftGenerationSettingsMovedMessage) {} @else {} } } @if (canUpdateServalConfig) { {{ t("serval\_config") }} } } {{ t("community\_checking\_settings") }} {{ t("enable\_community_checking") }} @if (isCheckingEnabled) { {{ t("see\_others\_answers\_and\_comments") }} {{ t("hide\_community\_checking\_text") }} {{ t("export\_checking\_answers") }} {{ t("export\_marked\_for\_export") }} {{ t("export\_all") }} {{ t("export\_none") }} } {{ t("sharing\_settings") }} {{ t("sharing\_description") }}

{{ t("sharing\_paratext\_members") }}

{{ t("sharing\_administrators") }} {{ t("sharing\_translators") }}

{{ t("sharing\_scripture\_forge\_guests") }}

@if (isCheckingEnabled) { {{ t("sharing\_community\_checkers") }} {{ i18n.localizeRoleDescription(SFProjectRole.CommunityChecker) }} } {{ t("sharing\_commenters") }} {{ i18n.localizeRoleDescription(SFProjectRole.Commenter) }} {{ t("sharing\_viewers") }} {{ i18n.localizeRoleDescription(SFProjectRole.Viewer) }}

{{ t("danger\_zone") }}

{{ t("delete\_this\_project") }} @if (isActiveSourceProject) { {{ t("source\_projects\_cannot\_be\_deleted") }} } @else if (isProjectSyncing) { {{ t("cannot\_delete\_project\_while\_syncing") }} } @else { {{ t("delete\_project\_cannot\_be\_undone") }} {{ synchronizeWarning?.templateTagText }} {{ synchronizeWarning?.after }} } {{ t("delete\_this\_project") }} ``` -------------------------------- ### Conditional Rendering Logic Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/lynx/insights/lynx-insights-panel/lynx-insights-panel.component.html Demonstrates conditional rendering based on node loading, dismissal, and expansion states. It also includes logic for displaying child counts and optimization indicators. ```C# @if (node.isLoading) { {{ node.description }} } @else { {{ node.description }} @if (node.isDismissed) { visibility_on } } {{ parentNodeRef.isExpanded ? "expand_more" : "chevron_right" }} @switch (currentLevel) { @case (0) { {{ node.description }} {{ node.count }} } } @if ( parentNodeRef.isExpanded && node.children && node.children.length > lynxInsightConfig.panelOptimizationThreshold ) { @if (node.remainingChildCount > 0) { @if (node.loadingProgressPercent < 100) { {{ t("loading") }} } @else { {{ t("show_more") }} ({{ node.remainingChildCount }} {{ t("remaining") }}) } } } ``` -------------------------------- ### Conditional Audio Playback Logic Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/checking/checking/single-button-audio-player/single-button-audio-player.component.html This snippet demonstrates conditional rendering logic based on audio availability and initialization status. It uses C# syntax within a Razor-like templating engine. ```C# @if (isAudioAvailable) { } @else if (audioStatus === AudioStatus.Initializing) { } @else { play_disabled } ``` -------------------------------- ### Manage Paratext Projects Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/my-projects/my-projects.component.html Handles the display and connection of Paratext projects. It shows loading states, error messages, offline status, and allows users to connect or join projects based on their permissions and project status. ```html @if (userIsPTUser) { @if ( userUnconnectedParatextProjects.length > 0 || loadingPTProjects || problemGettingPTProjects || (isOnline | async) === false ) { {{ loadingPTProjects ? t("loading_more_pt_projects") : userConnectedProjects.length === 0 ? t("connect_a_project_to_get_started") : t("not_connected") }} ------------------------------------------------------------------------------------------------------------------------------------------------------------------ } @if (problemGettingPTProjects) { {{ t(errorMessage) }} } @if ((isOnline | async) === false) { {{ t("offline") }} } @for (ptProject of userUnconnectedParatextProjects; track ptProject) { **{{ ptProject.shortName }}** - {{ ptProject.name }} @if (!ptProject.isConnectable) { {{ t("not_admin_cannot_connect_project") }} } @if (ptProject.isConnectable && ptProject.projectId == null) { {{ "connect_project.connect" | transloco }} } @if (ptProject.isConnectable && ptProject.projectId != null) { {{ t("join") }} } } @if (loadingPTProjects) { } } ``` -------------------------------- ### Adding a New Serval Environment Source: https://github.com/eon-dev1/web-xforge/blob/master/tools/ServalBuildReport/README.md Commands to add a new Serval environment (e.g., 'Test') by setting user secrets for ApiServer, Audience, ClientId, ClientSecret, and TokenUrl. ```dotnet dotnet user-secrets set "Test:ApiServer" "api_server_goes_here" dotnet user-secrets set "Test:Audience" "audience_goes_here" dotnet user-secrets set "Test:ClientId" "client_id_goes_here" dotnet user-secrets set "Test:ClientSecret" "client_secret_goes_here" dotnet user-secrets set "Test:TokenUrl" "token_url_goes_here" dotnet run test ``` -------------------------------- ### Conditional Download UI Logic Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-download-button/draft-download-button.component.html This snippet demonstrates conditional rendering based on 'flat' and 'downloadProgress' variables. It displays different icons and text depending on whether a download is in progress or complete, and whether the UI is in a 'flat' mode. ```C# @if (flat) { @if (downloadProgress === 0) { cloud_download } @else if (downloadProgress > 0) { } {{ t("download_draft") }} } @else { @if (downloadProgress === 0) { cloud_download } @else if (downloadProgress > 0) { } {{ t("download_draft") }} } ``` -------------------------------- ### Record Test with Playwright Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/e2e/README.md Demonstrates how to initiate test recording with Playwright. This can be done via the command line or by pausing execution within a test script. ```bash npx playwright codegen ``` -------------------------------- ### Project Settings Save Status Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Shows the status of saving project settings, including states for submitting, submitted (saved), and errors. ```html @if (getControlState("projectSettings") != null) { {{ t("saving_draft_sources") }} @if (getControlState("projectSettings") === ElementState.Submitting) { {{ t("saving") }} } @else if (getControlState("projectSettings") === ElementState.Submitted) { checkmark {{ t("all_changes_saved") }} } @else { error Failed to save changes } } ``` -------------------------------- ### Project Sync Status Display Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-sources/draft-sources.component.html Displays the synchronization status for various projects, indicating whether they are connecting, syncing, or have successfully/failed to sync. ```html @for (entry of syncStatus | keyvalue; track entry.key) { @if (entry.value.knownToBeOnSF) { @if (entry.value.isSyncing) { {{ entry.value.shortName }} - {{ t("state_syncing") }} } @else { @if (entry.value.lastSyncSuccessful) { check {{ entry.value.shortName }} - {{ t("state_sync_successful") }} } @else { error {{ entry.value.shortName }} - {{ t("state_sync_failed") }} } } } @else { {{ entry.value.shortName }} - {{ t("state_connecting") }} } } ``` -------------------------------- ### Iterating Through Books Source: https://github.com/eon-dev1/web-xforge/blob/master/src/SIL.XForge.Scripture/ClientApp/src/app/shared/book-chapter-chooser/book-chapter-chooser.component.html This snippet demonstrates iterating through a list of books using a for loop and displaying the book name. ```html @for (b of books; track b) { {{ bookName(b) }} } ```