{"version":3,"file":"application-CANcbsTb.js","sources":["../../../app/javascript/src/confirm.ts","../../../app/javascript/src/direct_uploads.ts","../../../app/javascript/src/lazysrc.ts","../../../app/javascript/src/turbo_error_handling.ts","../../../app/javascript/helpers/index.ts","../../../app/javascript/controllers/account_code_select_controller.ts","../../../app/javascript/controllers/account_finder_controller.ts","../../../app/javascript/controllers/account_number_generator_controller.ts","../../../app/javascript/controllers/account_search_dropdown_controller.ts","../../../app/javascript/controllers/account_select_for_intercompany_controller.ts","../../../app/javascript/controllers/account_select_for_ledger_controller.ts","../../../app/javascript/controllers/account_template_select_controller.ts","../../../app/javascript/controllers/account_typeahead_search_controller.ts","../../../app/javascript/channels/consumer.ts","../../../app/javascript/controllers/accounts_controller.ts","../../../app/javascript/controllers/action_modal_controller.ts","../../../app/javascript/controllers/active_account_selector_controller.ts","../../../app/javascript/controllers/addepar_transaction_filter_controller.ts","../../../app/javascript/controllers/addepar_transaction_filter_preview_controller.ts","../../../app/javascript/helpers/reports/formatters.ts","../../../app/javascript/helpers/register/csv_exporter.ts","../../../app/javascript/helpers/register/renderers.ts","../../../app/javascript/helpers/register/set_filters.ts","../../../app/javascript/helpers/register/server_side_datasource.ts","../../../app/javascript/controllers/advanced_register_controller.ts","../../../app/javascript/controllers/attachment_delete_controller.ts","../../../app/javascript/controllers/auto_click_controller.ts","../../../app/javascript/controllers/auto_reload_controller.ts","../../../app/javascript/controllers/auto_submit_controller.ts","../../../app/javascript/controllers/autohide_controller.ts","../../../app/javascript/controllers/bank_register_controller.ts","../../../app/javascript/controllers/bank_transaction_controller.ts","../../../app/javascript/helpers/reports/node_helpers.ts","../../../app/javascript/helpers/reports/renderers.ts","../../../app/javascript/helpers/budget_analysis/variance_helpers.ts","../../../app/javascript/helpers/budget_analysis/renderers.ts","../../../app/javascript/helpers/budget_analysis/excel_options.ts","../../../app/javascript/controllers/budget_analysis_controller.ts","../../../app/javascript/controllers/budget_analysis_datepicker_controller.ts","../../../app/javascript/controllers/budget_overview_controller.ts","../../../app/javascript/controllers/budget_table_sticky_controller.ts","../../../app/javascript/controllers/bulk_controller.ts","../../../app/javascript/controllers/bulk_update_ledger_entries_controller.ts","../../../app/javascript/controllers/cash_flow_defaults_controller.ts","../../../app/javascript/controllers/cell_nav_controller.ts","../../../app/javascript/controllers/checkbox_select_all_controller.ts","../../../app/javascript/controllers/checkbox_select_group_controller.ts","../../../app/javascript/controllers/click_hidden_controller.ts","../../../app/javascript/controllers/clipboard_controller.ts","../../../app/javascript/controllers/compare_to_last_period_button_controller.ts","../../../app/javascript/controllers/connected_transaction_controller.ts","../../../app/javascript/controllers/connected_transactions_controller.ts","../../../app/javascript/helpers/currency_formatter.ts","../../../app/javascript/controllers/copy_amount_controller.ts","../../../app/javascript/controllers/counter_controller.ts","../../../app/javascript/controllers/currency_subtotal_controller.ts","../../../app/javascript/helpers/date_range_option_parser.ts","../../../app/javascript/controllers/datepicker_controller.ts","../../../app/javascript/controllers/drag_controller.ts","../../../app/javascript/controllers/dropdown_with_tooltip_controller.ts","../../../app/javascript/controllers/dropzone_controller.ts","../../../app/javascript/controllers/dynamic_select_controller.ts","../../../app/javascript/controllers/enter_submit_controller.ts","../../../app/javascript/controllers/entity_graph_controller.ts","../../../app/javascript/controllers/entity_relationship_form_controller.ts","../../../app/javascript/controllers/finicity_controller.ts","../../../app/javascript/controllers/flowbite_modal_controller.ts","../../../app/javascript/controllers/frame_loader_controller.ts","../../../app/javascript/helpers/reports/index.ts","../../../app/javascript/helpers/reports/utils.ts","../../../app/javascript/helpers/relative_dates.ts","../../../app/javascript/helpers/reports/saved_reports.ts","../../../app/javascript/helpers/reports/excel_options.ts","../../../app/javascript/helpers/reports/overlays.ts","../../../app/javascript/controllers/general_ledger_controller.ts","../../../app/javascript/controllers/ignore_transaction_controller.ts","../../../app/javascript/controllers/input_currency_formatter_controller.ts","../../../app/javascript/helpers/one_schema/index.ts","../../../app/javascript/controllers/journal_entry_importer_controller.ts","../../../app/javascript/controllers/ledger_entries_controller.ts","../../../app/javascript/controllers/ledger_name_controller.ts","../../../app/javascript/controllers/ledger_select_controller.ts","../../../app/javascript/controllers/ledger_transaction_controller.ts","../../../app/javascript/controllers/ledger_transaction_notices_controller.ts","../../../app/javascript/controllers/mapping_manager_importer_controller.ts","../../../app/javascript/controllers/nested_addepar_transaction_filter_controller.ts","../../../app/javascript/controllers/nested_form_controller.ts","../../../app/javascript/controllers/nested_ledger_entry_controller.ts","../../../app/javascript/controllers/nested_rule_conditions_controller.ts","../../../app/javascript/controllers/net_cash_flow_toggle_controller.ts","../../../app/javascript/controllers/notifications_controller.ts","../../../app/javascript/controllers/optional_object_controller.ts","../../../app/javascript/controllers/ordinal_controller.ts","../../../app/javascript/controllers/ownership_to_partnership_controller.ts","../../../app/javascript/controllers/payable_controller.ts","../../../app/javascript/controllers/payable_line_items_controller.ts","../../../app/javascript/helpers/button_helpers.ts","../../../app/javascript/controllers/payable_type_controller.ts","../../../app/javascript/controllers/payment_terms_controller.ts","../../../app/javascript/controllers/plaid_controller.ts","../../../app/javascript/controllers/plaid_update_controller.ts","../../../app/javascript/controllers/radio_select_all_controller.ts","../../../app/javascript/controllers/reconciliation_checkbox_select_all_controller.ts","../../../app/javascript/controllers/reconciliation_controller.ts","../../../app/javascript/controllers/removable_controller.ts","../../../app/javascript/controllers/reporting_controller.ts","../../../app/javascript/controllers/reporting_datepicker_controller.ts","../../../app/javascript/controllers/reporting_row_options_controller.ts","../../../app/javascript/controllers/rule_preview_controller.ts","../../../app/javascript/controllers/saved_register_view_controller.ts","../../../app/javascript/controllers/saving_message_controller.ts","../../../app/javascript/controllers/scroll_to_controller.ts","../../../app/javascript/controllers/select_all_top_checkbox_controller.ts","../../../app/javascript/controllers/select_controller.ts","../../../app/javascript/controllers/select_toggle_controller.ts","../../../app/javascript/controllers/slideover_content_controller.ts","../../../app/javascript/controllers/sticky_dropdown_controller.ts","../../../app/javascript/controllers/sticky_table_controller.ts","../../../app/javascript/controllers/stimulus_tooltip_controller.ts","../../../app/javascript/controllers/submit_controller.ts","../../../app/javascript/controllers/subtype_dropdown_controller.ts","../../../app/javascript/controllers/sum_it_color_picker_controller.ts","../../../app/javascript/controllers/table_controller.ts","../../../app/javascript/controllers/tag_select_controller.ts","../../../app/javascript/controllers/tax_classification_select_controller.ts","../../../app/javascript/controllers/template_controller.ts","../../../app/javascript/controllers/toggle_all_controller.ts","../../../app/javascript/controllers/toggle_class_controller.ts","../../../app/javascript/controllers/toggle_controller.ts","../../../app/javascript/controllers/toggle_disable_controller.ts","../../../app/javascript/controllers/toggle_permissions_controller.ts","../../../app/javascript/controllers/toggle_readonly_controller.ts","../../../app/javascript/controllers/transaction_payables_match_controller.ts","../../../app/javascript/controllers/transaction_transfer_controller.ts","../../../app/javascript/controllers/unsaved_changes_controller.ts","../../../app/javascript/controllers/uploaded_transactions_controller.ts","../../../app/javascript/controllers/url_history_handler_controller.ts","../../../app/javascript/controllers/vendor_select_controller.ts","../../../app/javascript/controllers/index.ts","../../../app/javascript/entrypoints/application.ts"],"sourcesContent":["// Custom TailwindCSS modals for confirm dialogs\n//\n// Example usage:\n//\n// <%= button_to \"Delete\", my_path, method: :delete, form: {\n// data: {\n// turbo_confirm: \"Are you sure?\",\n// turbo_confirm_description: \"This will delete your record. Enter the record name to confirm.\",\n// turbo_confirm_text: \"record name\"\n// }\n// } %>\n\nimport * as Turbo from \"@hotwired/turbo\";\n\nfunction insertConfirmModal(message: string, element: HTMLFormElement, button: HTMLElement) {\n let confirmInput = \"\";\n\n // button is nil if using link_to with data-turbo-confirm\n const confirmText = button?.dataset?.turboConfirmText || element.dataset.turboConfirmText;\n const description = button?.dataset?.turboConfirmDescription || element.dataset.turboConfirmDescription || \"\";\n\n if (confirmText) {\n confirmInput = ``;\n }\n const id = `confirm-modal-${new Date().getTime()}`;\n\n const content = `\n
\n
\n\n
\n

${message}

\n

${description}

\n\n ${confirmInput}\n\n
\n \n \n
\n
\n
\n
\n `;\n\n document.body.insertAdjacentHTML(\"beforeend\", content);\n const modal = document.getElementById(id);\n\n // Focus on the first button in the modal after rendering\n modal.querySelector(\"button\").focus();\n\n // Disable commit button until the value matches confirmText\n if (confirmText) {\n const commitButton = modal.querySelector(\"[data-behavior='commit']\") as HTMLButtonElement;\n commitButton.disabled = true;\n\n modal.querySelector(\"input[data-behavior='confirm-text']\").addEventListener(\"input\", (event) => {\n commitButton.disabled = (event.target as HTMLButtonElement).value != confirmText;\n });\n }\n\n return modal;\n}\n\nTurbo.config.forms.confirm = (message, element, button) => {\n const dialog = insertConfirmModal(message, element, button);\n\n return new Promise((resolve, _reject) => {\n dialog.querySelector(\"[data-behavior='cancel']\").addEventListener(\n \"click\",\n (_event) => {\n dialog.remove();\n resolve(false);\n },\n { once: true },\n );\n dialog.querySelector(\"[data-behavior='commit']\").addEventListener(\n \"click\",\n (_event) => {\n dialog.remove();\n resolve(true);\n },\n { once: true },\n );\n });\n};\n","addEventListener(\"direct-upload:initialize\", (event) => {\n const { target, detail } = event as CustomEvent;\n const { id, file } = detail;\n\n if (target) {\n (target as HTMLElement).insertAdjacentHTML(\n \"beforebegin\",\n `\n
\n
\n ${file.name}\n
\n `\n );\n }\n});\n\naddEventListener(\"direct-upload:start\", (event) => {\n const { id } = (event as CustomEvent).detail;\n const element = document.getElementById(`direct-upload-${id}`);\n\n element?.classList.remove(\"direct-upload--pending\");\n});\n\naddEventListener(\"direct-upload:progress\", (event) => {\n const { id, progress } = (event as CustomEvent).detail;\n const progressElement = document.getElementById(`direct-upload-progress-${id}`);\n\n if (progressElement) {\n progressElement.style.width = `${progress}%`;\n }\n});\n\naddEventListener(\"direct-upload:error\", (event) => {\n event.preventDefault();\n const { id, error } = (event as CustomEvent).detail;\n const element = document.getElementById(`direct-upload-${id}`);\n\n element?.classList.add(\"direct-upload--error\");\n element?.setAttribute(\"title\", error);\n});\n\naddEventListener(\"direct-upload:end\", (event) => {\n const { id } = (event as CustomEvent).detail;\n const element = document.getElementById(`direct-upload-${id}`);\n\n element?.classList.add(\"direct-upload--complete\");\n});\n\nexport {};\n","// Lazily loads elements with a data-src attribute.\n// This is useful for speeding up initial page rendering.\n//\n// \n// \n\ndocument.addEventListener(\"turbo:load\", () => {\n document.querySelectorAll(\"[data-src]\").forEach((element) => {\n element.setAttribute(\"src\", element.getAttribute(\"data-src\"));\n });\n});\n\nexport {};\n","addEventListener(\"turbo:frame-missing\", async (event: CustomEvent) => {\n event.preventDefault();\n // Latest PR hides this https://github.com/hotwired/turbo/pull/863\n const response = event.detail.response;\n\n // Show a helpful error message if the frame is missing, but redirect\n // if theres a server error or if the response was redirected.\n if (response.status < 500) {\n const target = event.target as HTMLDivElement;\n\n console.error(`A matching frame for #${target.id} was missing from response.`);\n\n if (response.redirected) {\n console.warn(`Turbo redirecting to ${response.url}`);\n\n event.detail.visit(response);\n } else {\n target.innerHTML = `There was an error in this request. Error code: ${target.id}-turbo-frame-missing.`;\n }\n } else {\n event.detail.visit(response);\n }\n});\n\nexport {};\n","export function getMetaValue(name: string) {\n const element = findElement(document.head, `meta[name=\"${name}\"]`);\n if (element) {\n return element.getAttribute(\"content\");\n }\n}\n\nexport function findElement(root: HTMLHeadElement | Document, selector: string) {\n if (typeof root == \"string\") {\n selector = root;\n root = document;\n }\n return root.querySelector(selector);\n}\n\nexport function removeElement(el: HTMLElement) {\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n}\n\nexport function insertAfter(el: HTMLElement, referenceNode: HTMLElement) {\n return referenceNode.parentNode?.insertBefore(el, referenceNode.nextSibling);\n}\n\nexport function loadingIcon() {\n return `\n
\n \n \n \n \n
\n `;\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\nimport TomSelect from \"tom-select\";\nimport { TomOption, TomInput } from \"tom-select/dist/cjs/types\";\nimport { loadingIcon } from \"../helpers\";\n\ninterface AccountCode {\n id: string;\n name: string;\n accountCodeGroupId: string;\n accountCodeGroupName: string;\n accountCodeGroupType: string;\n}\n\n// Connects to data-controller=\"account-code-select\"\nexport default class extends Controller {\n static values = {\n accountCodeUrl: String,\n classes: Array,\n itemClasses: Array,\n includeUncoded: {\n type: Boolean,\n default: false,\n },\n includeDropdownPlugin: {\n type: Boolean,\n default: false,\n },\n lock: Boolean,\n disabled: Boolean,\n id: String,\n useCustomTrigger: {\n type: Boolean,\n default: false,\n },\n plugins: {\n type: Array,\n default: [\"remove_button\"]\n }\n };\n\n static targets = [\"selectElement\",\"customTrigger\"];\n\n declare select: TomSelect;\n declare hasClassesValue: boolean;\n declare classesValue: string[];\n declare hasItemClassesValue: boolean;\n declare itemClassesValue: string[];\n declare includeUncodedValue: boolean;\n declare includeDropdownPluginValue: boolean;\n declare lockValue: boolean;\n declare disabledValue: boolean;\n declare accountCodeUrlValue: string;\n declare hasAccountCodeUrlValue: boolean;\n declare idValue: string;\n declare hasIdValue: string;\n declare useCustomTriggerValue: boolean;\n declare pluginsValue: string[];\n declare selectElementTarget: HTMLSelectElement;\n declare customTriggerTarget: HTMLElement;\n declare templateElements: Array;\n\n private mousedownListener: (event: MouseEvent) => void;\n private mouseupListener: () => void;\n private elementMousedownListener: (event: MouseEvent) => void;\n\n connect() {\n if (this.lockValue) {\n this.pluginsValue = [];\n }\n\n this.templateElements = Array.from(this.element.querySelectorAll(\"template\"));\n\n const options = {\n plugins: this.pluginsValue,\n preload: \"focus\",\n load: this.loadOptions.bind(this),\n score: this.scoreSearchResults,\n maxOptions: 100,\n hidePlaceholder: true,\n valueField: \"id\",\n labelField: \"name\",\n searchField: [\"name\"],\n optgroupField: \"accountCodeGroupId\",\n optgroupLabelField: \"accountCodeGroupName\",\n optgroupValueField: \"accountCodeGroupId\",\n onBlur: () => {\n // We want the options to reload when the user focuses on the select\n this.select.wrapper.classList.remove(\"preloaded\");\n this.select.clearOptions();\n this.select.settings.load = this.loadOptions.bind(this);\n },\n render: {\n option: (item: AccountCode, escape: (value: string) => string) => {\n if (item.id === \"uncoded\") {\n return this.buildUncodedOption(item, escape);\n } else if (item.id.startsWith(\"not_coded_with_\")) {\n return ``; // Don't render, this is a ghost option\n } else {\n return this.buildAccountCodeOption(item, escape);\n }\n },\n item: (item: AccountCode, escape: (value: string) => string) => {\n if (item.id === \"uncoded\" || item.id.startsWith(\"not_coded_with_\")) {\n return this.buildUncodedItem(item, escape);\n } else {\n return this.buildAccountCodeItem(item, escape);\n }\n },\n optgroup_header: (data: AccountCode, escape: (value: string) => string) => {\n if (data.accountCodeGroupId === \"uncoded\") {\n return \"\";\n }\n const optGroupHeader = this.tempEl(\"optgroupHeader\");\n optGroupHeader.firstElementChild.textContent = this.decodeHtmlEntities(escape(data.accountCodeGroupName));\n optGroupHeader.append(this.buildNoGroupButton(data));\n optGroupHeader.append(this.buildNewButton(data));\n return optGroupHeader;\n },\n loading: (_data, _escape) => {\n return `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n },\n },\n onItemAdd: (values: string[]) => {\n this.select.setTextboxValue(\"\");\n this.toggleUncodedSelection(values);\n },\n onInitialize: () => {\n if (this.allowAddNewButton()) {\n const dropdown = this.selectElementTarget.nextElementSibling.querySelector(\".ts-dropdown\");\n\n dropdown.appendChild(this.tempEl(\"fullNewButton\"));\n }\n },\n };\n\n this.select = new TomSelect(this.selectElementTarget as TomInput, options);\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n this.select.control.classList.add(className);\n });\n }\n\n if (this.lockValue) {\n this.select.lock();\n }\n\n if (this.disabledValue) {\n this.disableSelect();\n }\n\n if (this.useCustomTriggerValue) {\n this.setupCustomTrigger();\n if (this.element.parentElement) {\n this.element.parentElement.classList.remove(\"hidden\");\n }\n }\n }\n\n tempEl(templateName) {\n const template = this.templateElements.find((element) => {\n if (element.dataset.templateName === templateName) {\n return element;\n }\n });\n\n return template.content.firstElementChild.cloneNode(true) as HTMLElement;\n }\n\n allowAddNewButton() {\n const whitelist = [\n new RegExp(\"/ledger_management/journal_entries/new\"),\n new RegExp(\"/ledger_management/ledger_transactions/lt_(.*)/duplicate$\"),\n new RegExp(\"/ledger_management/ledger_transactions/lt_(.*)/reverse$\"),\n new RegExp(\"/account_reconciliation/connected_transactions\"),\n new RegExp(\"/payables_management(.*)\"),\n ];\n\n for (const regex of whitelist) {\n if (regex.test(window.location.href)) {\n return true;\n }\n }\n\n return false;\n }\n\n buildNoGroupButton(data) {\n if (!this.includeUncodedValue) {\n return \"\";\n }\n\n const iconNoAccountCodeGroupButton = this.tempEl(\"iconNoAccountCodeGroupButton\");\n const innerButton = iconNoAccountCodeGroupButton.firstElementChild as HTMLElement;\n\n innerButton.setAttribute(\"data-action\", \"click->account-code-select#addNoGroupAccountCode\");\n innerButton.setAttribute(\"data-account-code-group-id\", data.accountCodeGroupId);\n\n return iconNoAccountCodeGroupButton;\n }\n\n addNoGroupAccountCode(event) {\n const accountCodeGroupId = event.currentTarget.dataset.accountCodeGroupId;\n this.select.addItem(`not_coded_with_${accountCodeGroupId}`);\n\n // remove any other account codes from the account code group\n for (const value in this.select.options) {\n const accountCode = this.select.options[value];\n const codeInAccountCodeGroup =\n accountCode.accountCodeGroupId === accountCodeGroupId &&\n accountCode.id !== `not_coded_with_${accountCodeGroupId}`;\n if (codeInAccountCodeGroup || accountCode.id === \"uncoded\") {\n this.select.removeItem(accountCode.id);\n }\n }\n }\n\n buildNewButton(data) {\n if (!this.allowAddNewButton() || data.accountCodeGroupType === \"system\") {\n return \"\";\n }\n\n const iconNewButton = this.tempEl(\"iconNewButton\");\n const innerButton = iconNewButton.firstElementChild as HTMLElement;\n const card = JSON.parse(innerButton.dataset.card);\n const cardTurboSrcUrl = new URL(card.turboSrc, window.location.origin);\n cardTurboSrcUrl.searchParams.append(\"account_code_group_id\", data.accountCodeGroupId);\n\n card.turboSrc = cardTurboSrcUrl.pathname + cardTurboSrcUrl.search;\n card.turboId = `account_code_form_with_group_${data.accountCodeGroupId}_account_code`;\n\n innerButton.dataset.card = JSON.stringify(card);\n\n return iconNewButton;\n }\n\n handleIdEnabledEvent(event) {\n const isEnabled = event.detail.enabled;\n const id = event.detail.id;\n\n if (this.hasIdValue && this.idValue === id) {\n if (isEnabled) {\n this.enableSelect();\n } else {\n this.disableSelect();\n }\n }\n }\n\n handleToggleEvent(event) {\n const isChecked = event.detail.checked;\n\n if (isChecked) {\n this.disableSelect();\n } else {\n this.enableSelect();\n }\n }\n\n enableSelect() {\n this.select.enable();\n }\n\n disableSelect() {\n this.select.disable();\n this.select.clear();\n }\n\n unfocusSelect() {\n this.select.blur();\n }\n\n disconnect() {\n this.cleanupEventListeners();\n this.select.destroy();\n }\n\n toggleUncodedSelection(values: string[]) {\n const isUncodedSelected = values.includes(\"uncoded\");\n\n if (isUncodedSelected) {\n for (const value in this.select.options) {\n const accountCode = this.select.options[value];\n if (accountCode.id !== \"uncoded\") {\n this.select.removeItem(accountCode.id);\n }\n }\n } else {\n this.select.removeOption(\"uncoded\");\n }\n\n // get all account code group ids from the selected account codes\n let notCodedWithAccountCodeGroupIds: string[] = [];\n if (Array.isArray(values)) {\n const notCodedWithAccountCodeGroupIds = [];\n values.map((id) => {\n if (!id.startsWith(\"not_coded_with_\")) {\n notCodedWithAccountCodeGroupIds.push(`not_coded_with_${this.select.options[id].accountCodeGroupId}`);\n }\n });\n } else {\n if (!(values as string).startsWith(\"not_coded_with_\")) {\n notCodedWithAccountCodeGroupIds = [`not_coded_with_${this.select.options[values].accountCodeGroupId}`];\n }\n }\n\n // we want to remove any pre-existing not_coded_with options if we select an account code\n // with an account group id that matches the not_coded_with option\n for (const value in this.select.options) {\n const accountCode = this.select.options[value];\n if (notCodedWithAccountCodeGroupIds.includes(accountCode.id)) {\n this.select.removeItem(accountCode.id);\n }\n }\n }\n\n // Build out the optgroup data structure for TomSelect\n buildOptGroups(accountCodes: AccountCode[]): TomOption[] {\n const accountCodeGroups = accountCodes.reduce((groups, accountCode) => {\n if (!groups[accountCode.accountCodeGroupId]) {\n groups[accountCode.accountCodeGroupId] = {\n accountCodeGroupName: accountCode.accountCodeGroupName,\n accountCodeGroupId: accountCode.accountCodeGroupId,\n accountCodeGroupType: accountCode.accountCodeGroupType,\n };\n }\n return groups;\n }, {});\n\n if (this.includeUncodedValue) {\n accountCodeGroups[0] = this.uncodedAccountCodeGroupDefinition();\n }\n\n return Object.values(accountCodeGroups);\n }\n\n loadOptions(\n _query: string,\n callback: (accountCodes: AccountCode[] | void, optionGroups: TomOption[] | void) => void,\n ) {\n if (this.select.loading > 1) {\n callback();\n return;\n }\n\n get(this.accountCodeUrlValue, { responseKind: \"json\" })\n .then((response: Response) => response.json)\n .then((payload: AccountCode[]) => {\n const optionGroups = this.buildOptGroups(payload);\n\n if (this.includeUncodedValue) {\n // Add \"Uncoded\" to the beginning of the list\n payload.unshift(this.uncodedAccountCodeDefinition());\n\n // for each optionGroup, build an option for not having that account code group\n for (const optionGroup of optionGroups) {\n payload.push(this.notCodedWithAccountCodeGroupDefinition(optionGroup));\n }\n }\n\n callback(payload, optionGroups);\n\n // We only want to load the data once, so we set the load function to null\n this.select.settings.load = null;\n })\n .catch((error) => {\n console.error(error);\n\n callback();\n });\n }\n\n scoreSearchResults(search) {\n return (item) => {\n let score = 0;\n\n const lowerCaseName = item.name.toLowerCase();\n const lowerCaseAccountCodeGroupName = item.accountCodeGroupName.toLowerCase();\n const lowerCaseSearch = search.toLowerCase();\n\n if (lowerCaseName === lowerCaseSearch) {\n score = 1;\n } else if (lowerCaseName.includes(lowerCaseSearch)) {\n score = 0.75;\n } else if (lowerCaseAccountCodeGroupName === lowerCaseSearch) {\n score = 0.5;\n } else if (lowerCaseAccountCodeGroupName.includes(lowerCaseSearch)) {\n score = 0.25;\n }\n\n return score;\n };\n }\n\n buildUncodedOption(item, escape: (value: string) => string) {\n const style = `style=\"background-color: #ffffff; color: #000000;\"`;\n return `\n
\n \n ${escape(item.name)}\n \n
\n `;\n }\n\n buildAccountCodeOption(item, escape: (value: string) => string) {\n const style = `style=\"background-color: #E1EFFE; color: #6A6A6A;\"`;\n return `\n
\n \n ${escape(item.name)}\n \n
\n `;\n }\n\n buildUncodedItem(item, escape: (value: string) => string) {\n const style = `style=\"background-color: #ffffff; color: #000000;\"`;\n return `\n
\n ${escape(item.name)}\n
\n `;\n }\n\n buildAccountCodeItem(item, escape: (value: string) => string) {\n const style = `style=\"background-color: #E1EFFE; color: #6A6A6A;\"`;\n let itemClasses = \"\";\n if (this.hasItemClassesValue) {\n itemClasses = this.itemClassesValue.join(\" \");\n }\n return `\n
\n ${escape(item.accountCodeGroupName + \": \" + item.name)}\n
\n `;\n }\n\n uncodedAccountCodeGroupDefinition() {\n return {\n accountCodeGroupName: \"Uncoded\",\n accountCodeGroupId: \"uncoded\",\n accountCodeGroupType: \"system\",\n };\n }\n\n uncodedAccountCodeDefinition() {\n return {\n id: \"uncoded\",\n name: \"Uncoded\",\n colorBg: \"#ffffff\",\n colorFg: \"#000000\",\n accountCodeGroupId: \"uncoded\",\n accountCodeGroupName: \"Uncoded\",\n accountCodeGroupType: \"system\",\n };\n }\n\n notCodedWithAccountCodeGroupDefinition(optionGroup) {\n return {\n id: `not_coded_with_${optionGroup.accountCodeGroupId}`,\n name: `Not Coded w/ ${optionGroup.accountCodeGroupName}`,\n colorBg: \"#ffffff\",\n colorFg: \"#000000\",\n accountCodeGroupId: optionGroup.accountCodeGroupId,\n accountCodeGroupName: optionGroup.accountCodeGroupName,\n accountCodeGroupType: optionGroup.accountCodeGroupType,\n };\n }\n\n // creates a temporary
, assigns the encoded string to its innerHTML, and retrieves\n // the decoded string from textContent to display special characters properly\n decodeHtmlEntities(encodedString) {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = encodedString;\n return tempDiv.textContent || tempDiv.innerText || \"\";\n }\n\n private setupCustomTrigger() {\n this.hideDefaultControl();\n this.setupCustomTriggerEvents();\n }\n\n private hideDefaultControl() {\n const control = this.select.wrapper.querySelector('.ts-control') as HTMLElement;\n if (control) {\n control.style.display = 'none';\n }\n }\n\n private setupCustomTriggerEvents() {\n let isClosing = false;\n\n // Store the listeners so we can remove them later\n this.mousedownListener = (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.select.isOpen) {\n isClosing = true;\n this.select.close();\n } else {\n this.select.open();\n }\n };\n\n this.mouseupListener = () => {\n setTimeout(() => { isClosing = false; }, 100);\n };\n\n this.elementMousedownListener = (event: MouseEvent) => {\n if (isClosing) {\n event.stopPropagation();\n }\n };\n\n this.customTriggerTarget.addEventListener('mousedown', this.mousedownListener);\n this.customTriggerTarget.addEventListener('mouseup', this.mouseupListener);\n this.element.addEventListener('mousedown', this.elementMousedownListener);\n }\n\n private cleanupEventListeners() {\n if (this.mousedownListener) {\n this.customTriggerTarget.removeEventListener('mousedown', this.mousedownListener);\n }\n if (this.mouseupListener) {\n this.customTriggerTarget.removeEventListener('mouseup', this.mouseupListener);\n }\n if (this.elementMousedownListener) {\n this.element.removeEventListener('mousedown', this.elementMousedownListener);\n }\n }\n\n reconnect() {\n this.disconnect();\n this.connect();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport * as Turbo from \"@hotwired/turbo\";\n\nexport default class extends Controller {\n static targets = [\"input\", \"results\", \"emptyResultMessage\"];\n static values = {\n url: String,\n resultCount: Number\n };\n\n declare inputTarget: HTMLInputElement;\n declare resultsTarget: HTMLElement;\n declare emptyResultMessageTarget: HTMLElement;\n declare urlValue: string;\n declare resultCountValue: number;\n\n async search() {\n if (this.inputTarget.value.length > 2) {\n const response = await fetch(`${this.urlValue}?q=${encodeURIComponent(this.inputTarget.value)}&count=${this.resultCountValue}`, {\n headers: {\n \"Accept\": \"text/vnd.turbo-stream.html\",\n },\n });\n const stream = await response.text();\n this.emptyResultMessageTarget.classList.add(\"hidden\");\n Turbo.renderStreamMessage(stream);\n } else {\n this.emptyResultMessageTarget.classList.remove(\"hidden\");\n this.resultsTarget.innerHTML = \"\";\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\n\n// Connects to data-controller=\"account-number-generator\"\nexport default class extends Controller {\n static targets = [\"parentAccount\"];\n static values = { url: String, disabled: Boolean };\n\n declare urlValue: string;\n declare disabledValue: boolean;\n\n declare parentAccountTarget: HTMLInputElement;\n declare hasParentAccountTarget: boolean;\n\n fetchAccountNumber() {\n if (!this.validParentAccountInput || this.disabledValue) {\n return;\n }\n\n const queryParams = new URLSearchParams({\n account_template_id: this.parentAccountTarget.value,\n }).toString();\n\n const fullUrl = this.buildAccountNumberUrl(queryParams);\n\n get(`${fullUrl}`, {\n responseKind: \"turbo-stream\",\n });\n }\n\n fetchNewNumber(event: Event) {\n event.preventDefault();\n this.fetchAccountNumber();\n }\n\n buildAccountNumberUrl(queryParams: string) {\n const url = new URL(this.urlValue, window.location.href);\n url.search = queryParams.toString();\n\n return url.toString();\n }\n\n get validParentAccountInput(): boolean {\n return this.hasParentAccountTarget && this.parentAccountTarget.value !== \"\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\ninterface HTMLAccountElement extends HTMLElement {\n textContent: string\n dataset: {\n accountId: string\n }\n}\n\ninterface Match {\n start: number\n end: number\n text: string\n}\n\nexport default class extends Controller {\n static targets = [\"searchInput\", \"accountItem\", \"noResults\"]\n\n declare searchInputTarget: HTMLInputElement\n declare accountItemTargets: HTMLAccountElement[]\n declare noResultsTarget: HTMLElement\n\n focusSearch() {\n this.searchInputTarget.focus()\n }\n\n submitFirstResult(event: KeyboardEvent) {\n event.preventDefault()\n\n const visibleItems = this.accountItemTargets.filter(\n item => item.style.display !== 'none'\n )\n\n if (visibleItems.length > 0) {\n const firstItem = visibleItems[0]\n const submitButton = firstItem.querySelector('button[type=\"submit\"]')\n if (submitButton instanceof HTMLButtonElement) {\n submitButton.click();\n }\n }\n }\n\n handleEscape() {\n // Clear the search input\n this.searchInputTarget.value = '';\n this.filterAccounts();\n\n // Unfocus the input\n this.searchInputTarget.blur();\n\n // Dispatch event to close dropdown\n this.dispatch(\"closeMenu\");\n }\n\n filterAccounts() {\n const searchTerms = this.getSearchTerms()\n let hasVisibleItems = false\n\n this.accountItemTargets.forEach(item => {\n // Store original text for matching\n const originalText = item.textContent?.trim() || \"\"\n const matches = this.textMatchesAllTerms(originalText, searchTerms)\n\n this.updateItemVisibility(item, matches)\n if (matches) hasVisibleItems = true\n\n const accountTextElement = item.querySelector('.account-text')\n\n if (matches && searchTerms.length > 0) {\n accountTextElement.innerHTML = this.getHighlightedHtml(originalText, searchTerms)\n } else {\n accountTextElement.textContent = originalText\n }\n })\n\n this.noResultsTarget.style.display = hasVisibleItems ? \"none\" : \"block\"\n }\n\n private getSearchTerms(): string[] {\n return this.searchInputTarget.value\n .toLowerCase()\n .split(' ')\n .filter(term => term.length > 0)\n }\n\n private textMatchesAllTerms(text: string, searchTerms: string[]): boolean {\n return searchTerms.every(term => text.toLowerCase().includes(term))\n }\n\n private updateItemVisibility(item: HTMLElement, isVisible: boolean) {\n item.style.display = isVisible ? \"\" : \"none\"\n }\n\n private getHighlightedHtml(text: string, searchTerms: string[]): string {\n const matches = this.findAllMatches(text, searchTerms)\n const mergedMatches = this.mergeOverlappingMatches(matches)\n return this.buildHighlightedHtml(text, mergedMatches)\n }\n\n private findAllMatches(text: string, searchTerms: string[]): Match[] {\n const matches: Match[] = []\n searchTerms.forEach(term => {\n const regex = new RegExp(this.escapeRegExp(term), 'gi')\n let match\n while ((match = regex.exec(text)) !== null) {\n matches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[0]\n })\n }\n })\n return matches\n }\n\n /**\n * Merges overlapping text matches to prevent nested or overlapping highlights.\n * For example, if we have matches for \"test\" and \"testing\" in \"testing123\",\n * instead of having two separate matches at [0-4] and [0-7], we merge them\n * into a single match at [0-7].\n *\n * @param matches - Array of Match objects containing start/end positions\n * @returns Array of merged Match objects with no overlapping ranges\n *\n * Example:\n * Input: [{start: 0, end: 4}, {start: 0, end: 7}, {start: 10, end: 12}]\n * Output: [{start: 0, end: 7}, {start: 10, end: 12}]\n */\n private mergeOverlappingMatches(matches: Match[]): Match[] {\n if (matches.length === 0) return []\n\n const sortedMatches = [...matches].sort((a, b) => a.start - b.start)\n return sortedMatches.reduce((acc: Match[], curr) => {\n if (acc.length === 0) {\n acc.push(curr)\n return acc\n }\n\n const prev = acc[acc.length - 1]\n if (curr.start <= prev.end) {\n prev.end = Math.max(prev.end, curr.end)\n } else {\n acc.push(curr)\n }\n return acc\n }, [])\n }\n\n private buildHighlightedHtml(text: string, matches: Match[]): string {\n let result = ''\n let lastIndex = 0\n\n matches.forEach(match => {\n // Add text before match\n result += this.escapeHtml(text.substring(lastIndex, match.start))\n // Add highlighted match\n result += `${this.escapeHtml(text.substring(match.start, match.end))}`\n lastIndex = match.end\n })\n // Add remaining text\n result += this.escapeHtml(text.substring(lastIndex))\n\n return result\n }\n\n private escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n\n private escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n }\n}","import { Controller } from '@hotwired/stimulus';\n\n// Connects to data-controller=\"account-select-for-intercompany\"\nexport default class extends Controller {\n static targets = [\"debitAccount\", \"creditAccount\", \"select\", \"submitButton\"];\n\n declare debitAccountTarget: HTMLInputElement;\n declare creditAccountTarget: HTMLInputElement;\n declare submitButtonTarget: HTMLButtonElement;\n declare hasSubmitButtonTarget: boolean;\n declare selectTarget: HTMLSelectElement;\n\n static values = {\n submitId: String\n };\n declare submitIdValue: string;\n\n connect() {\n this.updateAccounts();\n }\n\n updateAccounts() {\n const select = this.selectTarget;\n const selectedOption = select[select.selectedIndex];\n\n if (selectedOption) {\n this.updateTargetValue(this.debitAccountTarget, selectedOption.dataset.intercompanyDebitAccountTemplateId);\n this.updateTargetValue(this.creditAccountTarget, selectedOption.dataset.intercompanyCreditAccountTemplateId);\n } else {\n this.debitAccountTarget.value = \"\";\n this.creditAccountTarget.value = \"\";\n }\n\n this.toggleSubmitButton();\n }\n\n // Updates the targets value with the value from the passed in argument. Verifies that\n // the value is a string that can be coerced into a number.\n updateTargetValue(target: HTMLInputElement, value: string) {\n if (value === \"\") {\n target.value = \"\";\n } else {\n const number = Number(value);\n\n if (isNaN(number)) {\n target.value = \"\";\n } else {\n target.value = number.toString();\n }\n }\n }\n\n toggleSubmitButton() {\n if (this.debitAccountTarget.value === \"\" && this.creditAccountTarget.value === \"\") {\n if (this.hasSubmitButtonTarget) {\n this.submitButtonTarget.disabled = true;\n } else {\n this.dispatch(\"toggleSubmit\", { detail: { enabled: false, id: this.submitIdValue } });\n }\n } else {\n if (this.hasSubmitButtonTarget) {\n this.submitButtonTarget.disabled = false;\n } else {\n this.dispatch(\"toggleSubmit\", { detail: { enabled: true, id: this.submitIdValue } });\n }\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus';\nimport { get } from '@rails/request.js';\n\n// Connects to data-controller=\"account-select-for-ledger\"\nexport default class extends Controller {\n static targets = [\"accountSelect\", \"ledgerSelect\"];\n\n static values = {\n url: String,\n classes: Array,\n posted: Boolean,\n cashAccountsOnly: { type: Boolean, default: false },\n accountTemplateId: Number\n };\n\n declare accountSelectTargets: HTMLSelectElement[];\n declare ledgerSelectTarget: HTMLSelectElement;\n declare urlValue: string;\n declare hasClassesValue: boolean;\n declare classesValue: string[];\n declare postedValue: boolean;\n declare cashAccountsOnlyValue: boolean;\n declare accountTemplateIdValue: number;\n\n ledgerChanged(_event: Event) {\n this.accountSelectTargets.forEach((selectTarget: HTMLSelectElement) => {\n this.getSelectTargetTurboFrame(selectTarget);\n });\n }\n\n getSelectTargetTurboFrame(element: HTMLSelectElement) {\n const selectedLedgerId = this.ledgerSelectTarget.hasChildNodes()\n ? this.ledgerSelectTarget.selectedOptions[0].value\n : this.ledgerSelectTarget.value;\n const selectedAccountId = element.hasChildNodes() ? element.selectedOptions[0].value : \"\";\n\n if (selectedLedgerId === \"\") {\n return;\n }\n\n // Don't reload if the ledger hasn't changed\n if (selectedLedgerId === element.dataset.ledgerId) {\n return;\n }\n\n const query = {\n ledger_id: selectedLedgerId,\n target: element.id,\n name: element.name,\n selected_account_id: selectedAccountId,\n cash_accounts_only: this.cashAccountsOnlyValue,\n account_template_id: this.accountTemplateIdValue,\n };\n\n if (this.hasClassesValue) {\n query[\"classes[]\"] = this.classesValue;\n }\n\n get(this.urlValue, {\n query: query,\n responseKind: \"turbo-stream\",\n });\n }\n\n accountSelectTargetConnected(element: HTMLElement) {\n if (this.postedValue) {\n return;\n }\n\n this.getSelectTargetTurboFrame(element as HTMLSelectElement);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\nimport TomSelect from \"tom-select\";\nimport { TomInput, TomOption } from \"tom-select/dist/cjs/types\";\nimport { loadingIcon } from \"../helpers\";\n\ninterface optgroup {\n label: string;\n value: string;\n}\n\ninterface account {\n id: number;\n label: string;\n type: string;\n}\n\n// Connects to data-controller=\"account-select\"\nexport default class extends Controller {\n static targets = [\"ledger\"];\n\n static values = {\n accountUrl: String,\n classes: Array,\n itemClasses: Array,\n lock: Boolean,\n accountNameAndNumber: String,\n maxOptions: { type: Number, default: 100 },\n };\n\n declare select: TomSelect;\n declare hasClassesValue: boolean;\n declare classesValue: string[];\n declare hasItemClassesValue: boolean;\n declare itemClassesValue: string[];\n declare lockValue: boolean;\n\n declare accountUrlValue: string;\n declare hasaccountUrlValue: boolean;\n\n declare ledgerTarget: HTMLSelectElement;\n\n declare maxOptionsValue: number;\n\n connect() {\n let plugins = [\"remove_button\"];\n\n if (this.lockValue) {\n plugins = [];\n }\n\n const options = {\n plugins: plugins,\n preload: \"focus\",\n maxOptions: this.maxOptionsValue,\n load: this.loadOptions.bind(this),\n hidePlaceholder: true,\n valueField: \"id\",\n labelField: \"label\",\n searchField: [\"label\"],\n optgroupField: \"type\",\n optgroupLabelField: \"type\",\n onBlur: () => {\n // We want the options to reload when the user focuses on the select\n this.select.wrapper.classList.remove(\"preloaded\");\n this.select.clearOptions();\n this.select.settings.load = this.loadOptions.bind(this);\n },\n sortField: [{ field: \"$order\" }, { field: \"$score\" }], // Maintain order of results by number while searching\n render: {\n optgroup_header: (data: optgroup, escape: (value: string) => string) => {\n const style = `style=\"background-color: #F1F2F5;\"`;\n return `\n
\n ${escape(data.value)}\n
\n `;\n },\n loading: (_data, _escape) => {\n return `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n },\n },\n onItemAdd: () => {\n this.select.setTextboxValue(\"\");\n },\n };\n\n this.select = new TomSelect(this.element as TomInput, options);\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n this.select.control.classList.add(className);\n });\n }\n\n if (this.lockValue) {\n this.select.lock();\n }\n }\n\n unfocusSelect() {\n this.select.blur();\n }\n\n disconnect() {\n this.select.destroy();\n }\n\n // Build out the optgroup data structure for TomSelect\n buildOptGroups(accounts: account[]): TomOption[] {\n const accountGroups = accounts.reduce((groups, account) => {\n if (!groups[account.type]) {\n groups[account.type] = {\n label: account.type,\n value: account.type,\n };\n }\n return groups;\n }, {});\n return Object.values(accountGroups);\n }\n\n loadOptions(_query: string, callback: (accounts: account[] | void, optionGroups: TomOption[] | void) => void) {\n if (this.select.loading > 1) {\n callback();\n return;\n }\n\n get(this.accountUrlValue, { responseKind: \"json\" })\n .then((response: Response) => response.json)\n .then((payload: account[]) => {\n const optionGroups = this.buildOptGroups(payload);\n\n callback(payload, optionGroups);\n\n // We only want to load the data once, so we set the load function to null\n this.select.settings.load = null;\n })\n .catch((error) => {\n console.error(error);\n\n callback();\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport TomSelect from \"tom-select\";\nimport { TomInput, TomOption } from \"tom-select/dist/cjs/types\";\nimport { get } from \"@rails/request.js\";\nimport { loadingIcon } from \"../helpers\";\n\n// Defined in app/views/ledger_management/accounts/_account.json.jbuilder\ninterface Account {\n id: number;\n name: string;\n number: string;\n label: string;\n type: string;\n}\n\n// Connects to data-controller=\"account-typeahead-search\"\nexport default class extends Controller {\n static values = {\n url: String,\n queryParam: { type: String, default: \"q\" },\n classes: Array,\n maxOptions: { type: Number, default: 100 },\n };\n\n declare select: TomSelect;\n declare hasClassesValue: boolean;\n declare classesValue: string[];\n declare urlValue: string;\n declare queryParamValue: string;\n declare maxOptionsValue: number;\n\n connect() {\n this.select = new TomSelect(this.element as TomInput, {\n plugins: [\"remove_button\"],\n preload: \"focus\",\n load: this.loadOptions.bind(this),\n labelField: \"label\",\n valueField: \"id\",\n searchField: [\"label\"],\n optgroupField: \"type\",\n optgroupLabelField: \"type\",\n optgroupValueField: \"type\",\n maxOptions: this.maxOptionsValue,\n onBlur: () => {\n // We want the options to reload when the user focuses on the select\n this.select.wrapper.classList.remove(\"preloaded\");\n this.select.clearOptions();\n this.select.settings.load = this.loadOptions.bind(this);\n },\n render: {\n optgroup_header: function (data, escape) {\n const style = `style=\"background-color: #F1F2F5;\"`;\n return `\n
\n ${escape(data.label)}\n
\n `;\n },\n item: function (item, escape) {\n return `\n
\n ${escape(item.label)}\n
\n `;\n },\n loading: (_data, _escape) => {\n return `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n },\n },\n });\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n this.select.control.classList.add(className);\n });\n }\n }\n\n buildURL(): string {\n const url = new URL(this.urlValue, window.location.href);\n\n return url.toString();\n }\n\n unfocusSelect() {\n this.select.blur();\n }\n\n disconnect() {\n this.select.destroy();\n }\n\n buildOptGroups(accounts: Account[]): TomOption[] {\n const accountGroups = accounts.reduce((groups, account) => {\n if (!groups[account.type]) {\n groups[account.type] = {\n label: account.type,\n type: account.type,\n };\n }\n return groups;\n }, {});\n\n return Object.values(accountGroups);\n }\n\n loadOptions(query: string, callback: (accounts: Account[] | void, optionGroups: TomOption[] | void) => void) {\n if (this.select.loading > 1) {\n callback();\n return;\n }\n\n get(this.buildURL(), { responseKind: \"json\" })\n .then((response: Response) => response.json)\n .then((payload: Account[]) => {\n const optionGroups = this.buildOptGroups(payload);\n\n callback(payload, optionGroups);\n\n // We only want to load the data once, so we set the load function to null\n this.select.settings.load = null;\n })\n .catch((error) => {\n console.error(error);\n\n callback();\n });\n }\n}\n","// Action Cable provides the framework to deal with WebSockets in Rails.\n// You can generate new channels where WebSocket features live using the `rails generate channel` command.\n\nimport { createConsumer } from \"@rails/actioncable\"\n\nexport default createConsumer()\n","// Reconnect ActionCable after switching accounts\n\nimport { Controller } from \"@hotwired/stimulus\";\nimport consumer from \"../channels/consumer\";\n\nexport default class extends Controller {\n reconnect(_event: Event) {\n if (consumer.connection.isActive()) {\n consumer.connection.reopen();\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus';\n\ninterface FeatureFlags {\n on: boolean,\n colors: boolean,\n names: boolean,\n};\n\n// Connects to data-controller=\"action-modal\"\nexport default class extends Controller {\n static targets = ['actionModal', 'cardWrapper', 'bodyStack', 'template'];\n\n declare actionModalTarget: HTMLElement;\n declare cardWrapperTarget: HTMLElement;\n declare bodyStackTarget: HTMLElement;\n\n declare templateTargets: Array;\n\n declare devFlags: FeatureFlags;\n\n declare handleCardTransitionEndBoundFn: (e) => void;\n declare handleActionModalTransitionEndBoundFn: (e) => void;\n\n connect() {\n this.devFlags = { on: false, colors: true, names: true };\n if ( this.devFlags.on ) this.startDevMode();\n }\n\n tempEl(templateName) {\n const template = this.templateTargets.find(element => {\n if (element.dataset.templateName === templateName) {\n return element;\n }\n });\n\n return template.content.firstElementChild.cloneNode(true) as HTMLElement;\n }\n\n push(event) {\n this.pushCardElementToStack(event.currentTarget);\n }\n\n pop(event) {\n if (event.currentTarget.dataset.backDropPoppable === 'false') return;\n\n event.preventDefault();\n this.popCardElementFromStack();\n\n return false;\n }\n\n pushCardElementToStack(buttonElement) {\n const card = JSON.parse(buttonElement.dataset.card);\n this.actionModalTarget.setAttribute('data-back-drop-poppable', card.backDropPoppable);\n this.bodyStackTarget.appendChild(this.buildTurboFrame(card));\n this.stackChanged();\n }\n\n popCardElementFromStack() {\n const isFirstCard = this.bodyStackTarget.children.length === 1;\n\n if (isFirstCard) {\n this.cardWrapperTarget.classList.remove(\"opacity-100\");\n this.handleCardTransitionEndBoundFn = this.handleCardTransitionEnd.bind(this);\n this.actionModalTarget.addEventListener('transitionend', this.handleCardTransitionEndBoundFn)\n } else {\n this.bodyStackTarget.removeChild(this.bodyStackTarget.lastElementChild);\n this.stackChanged();\n }\n }\n\n handleCardTransitionEnd(event) {\n if (event.propertyName === 'opacity' && this.bodyStackTarget.children.length === 1) {\n event.currentTarget.removeEventListener('transitionend', this.handleCardTransitionEndBoundFn);\n this.bodyStackTarget.removeChild(this.bodyStackTarget.lastElementChild);\n this.stackChanged();\n }\n }\n\n stackChanged() {\n const topCard = this.bodyStackTarget.lastElementChild as HTMLElement\n\n this.cardWrapperTarget.className = 'action-modal-card-wrapper';\n\n if (topCard) {\n // template-full template-fat template-slidover template-wideover template-modal-sm\n\n // This opacity-100 doesn't need the requestAnimationFrame because of how the browser\n // processes the reflow and repaint. Since the action modal, which is the parent, is hidden\n // the browser doesn't repaint the element until the action modal is displayed. Therefore\n // we don't need to trigger a reflow and repaint with requestAnimationFrame.\n // When the action modal is displayed, the browser will trigger a reflow and repaint. The\n // reason we'll need to use requestAnimationFrame for the action modal opacity changes is because\n // when the browser triggers the reflow/repaint it'll bundle the opacity-0 and opacity-100 changes together\n // and this would cause the browser to not know what to transition from. Using requestAnimationFrame\n // will allow the browser to separate the two changes and trigger the transition from opacity-0 to opacity-100 correctly.\n this.cardWrapperTarget.classList.add(\"opacity-100\");\n this.cardWrapperTarget.classList.add(\"template-\" + topCard.dataset.cardTemplate);\n this.show();\n } else {\n this.hide();\n }\n }\n\n show() {\n this.element.classList.add('overflow-hidden');\n this.actionModalTarget.classList.remove('hidden');\n requestAnimationFrame(() => {\n this.actionModalTarget.classList.remove('opacity-0');\n this.actionModalTarget.classList.add('opacity-100');\n })\n }\n\n hide() {\n this.element.classList.remove('overflow-hidden');\n this.actionModalTarget.classList.remove('opacity-100');\n this.actionModalTarget.classList.add('opacity-0');\n this.handleActionModalTransitionEndBoundFn = this.handleActionModalTransitionEnd.bind(this);\n this.actionModalTarget.addEventListener('transitionend', this.handleActionModalTransitionEndBoundFn)\n }\n\n handleActionModalTransitionEnd(event) {\n if (event.propertyName === 'opacity' && this.actionModalTarget?.classList?.contains('opacity-0')) {\n this.actionModalTarget.classList.add('hidden');\n event.target.removeEventListener('transitionend', this.handleActionModalTransitionEndBoundFn);\n }\n }\n\n buildTurboFrame(card) {\n const turboFrame = this.tempEl('turboFrame');\n\n if (this.devFlags.on) {\n turboFrame.dataset.action = \"turbo:frame-render->action-modal#addDevFeaturesToFrame\";\n }\n\n turboFrame.setAttribute('id', card.turboId);\n turboFrame.setAttribute('src', card.turboSrc);\n turboFrame.dataset.cardTemplate = card.cardTemplate;\n\n return turboFrame\n }\n\n clearStack() {\n this.bodyStackTarget.innerHTML = '';\n\n this.stackChanged();\n }\n\n startDevMode() {\n if (this.devFlags.colors) this.actionModalTarget.classList.add('dev');\n }\n\n addDevFeaturesToFrame(event) { \n const frame = event.target as HTMLElement;\n\n this.addDevNamesToChildren(frame) \n }\n\n addDevNamesToChildren(parentElement) {\n if (!this.devFlags.names) return;\n\n parentElement.querySelectorAll(`[class*=\"action-modal-\"]`).forEach( (element) => {\n const actionClass = element.className.match(/action-modal-[\\w-]+/)[0];\n const span = document.createElement('span');\n span.textContent = actionClass.replace('action-modal-', '');\n span.classList.add('text-xs', 'text-gray-100', 'absolute', 'block', 'top-0', 'left-0', 'px-1', 'bg-blue-500', 'whitespace-nowrap', 'group-hover:hidden');\n\n if (actionClass.match('button$')) {\n span.classList.add('bottom-0', 'right-0');\n span.classList.remove('top-0', 'left-0');\n }\n\n element.appendChild(span);\n element.classList.add('relative', 'group');\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\n\n// Connects to data-controller=\"active-account-selector\"\nexport default class extends Controller {\n static targets = [\"button\", \"cancelButton\", \"accountQuery\", \"ledgerIds\", \"fieldset\"];\n static values = {\n accountMatrixReadonly: Boolean,\n updatePath: String,\n };\n\n declare fieldsetTarget: HTMLFieldSetElement;\n declare hasFieldsetTarget: boolean;\n declare buttonTarget: HTMLButtonElement;\n declare accountQueryTarget: HTMLInputElement;\n declare ledgerIdsTarget: HTMLSelectElement;\n declare accountMatrixReadonlyValue: boolean;\n declare updatePathValue: string;\n\n connect() {\n this.buttonTarget.disabled = !this.hasFieldsetTarget;\n }\n\n toggleEditing() {\n if (this.accountMatrixReadonlyValue) {\n this.enableEditing();\n } else {\n this.disableEditing();\n }\n }\n\n fieldsetTargetConnected() {\n this.accountMatrixReadonlyValue = true;\n this.buttonTarget.disabled = false;\n }\n\n fieldsetTargetDisconnected() {\n this.accountMatrixReadonlyValue = true;\n this.buttonTarget.disabled = true;\n }\n\n enableEditing() {\n this.accountMatrixReadonlyValue = false;\n }\n\n disableEditing() {\n this.accountMatrixReadonlyValue = true;\n }\n\n setCheckboxes(checkboxDisabled: boolean) {\n this.fieldsetTarget.disabled = checkboxDisabled;\n }\n\n accountMatrixReadonlyValueChanged() {\n if (!this.hasFieldsetTarget) {\n return;\n }\n\n if (this.accountMatrixReadonlyValue) {\n this.fieldsetTarget.disabled = true;\n this.buttonTarget.textContent = \"Edit Accounts\";\n this.buttonTarget.classList.remove(\"btn-white\");\n this.buttonTarget.classList.add(\"btn-primary\");\n } else {\n this.fieldsetTarget.disabled = false;\n this.buttonTarget.textContent = \"Stop Editing\";\n this.buttonTarget.classList.add(\"btn-white\");\n this.buttonTarget.classList.remove(\"btn-primary\");\n }\n }\n\n async updateHiddenInput(event: Event) {\n this.setCheckboxes(true);\n this.buttonTarget.disabled = true;\n const clickedCheckbox = event.target as HTMLInputElement;\n\n await post(this.updatePathValue, {\n body: {\n id: clickedCheckbox.id,\n active: clickedCheckbox.checked,\n ledger_ids: this.ledgerIds(),\n },\n responseKind: \"turbo-stream\",\n });\n\n this.buttonTarget.disabled = false;\n this.setCheckboxes(false);\n }\n\n ledgerIds(): string[] {\n return Array.from(this.ledgerIdsTarget.options)\n .filter((option) => option.selected)\n .map((option) => option.value);\n }\n}\n","import { Controller } from '@hotwired/stimulus';\nimport { get } from '@rails/request.js';\n\n// Connects to data-controller=\"addepar-transaction-filter\"\nexport default class extends Controller {\n static targets = [\"addeparFieldSelect\", \"operatorSelect\", \"value\", \"updateContainer\"];\n\n static values = {\n url: String,\n addeparImportId: Number\n };\n\n declare addeparFieldSelectTarget: HTMLSelectElement;\n declare operatorSelectTarget: HTMLSelectElement;\n declare valueTarget: HTMLInputElement;\n declare urlValue: string;\n declare addeparImportIdValue: number;\n declare updateContainerTarget: HTMLDivElement;\n\n addeparFieldChanged(_event: Event) {\n this.getSelectTargetTurboFrame(this.addeparFieldSelectTarget);\n }\n\n getSelectTargetTurboFrame(element: HTMLSelectElement) {\n const selectedAddeparField = this.addeparFieldSelectTarget.value;\n\n // Don't reload if the field hasn't changed or is empty\n if (selectedAddeparField === \"\" || selectedAddeparField === element.dataset.addeparField) {\n return;\n }\n\n const query = {\n addepar_import_id: this.addeparImportIdValue,\n selected_addepar_field: selectedAddeparField,\n target: this.updateContainerTarget.id,\n name: element.name,\n operator_name: this.operatorSelectTarget.name,\n value_name: this.valueTarget.name,\n };\n\n get(this.urlValue, {\n query: query,\n responseKind: \"turbo-stream\",\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\n\n// Connects to data-controller=\"addepar-transaction-filter-preview\"\nexport default class extends Controller {\n static targets = [\"form\", \"previewButton\", \"previewPane\"];\n\n static values = {\n url: String,\n };\n\n declare urlValue: string;\n\n declare formTarget: HTMLFormElement;\n declare previewButtonTarget: HTMLButtonElement;\n declare hasPreviewButtonTarget: boolean;\n\n declare previewPaneTarget: HTMLDivElement;\n\n connect() {\n this.getPreview();\n }\n\n togglePreviewPane() {\n this.previewPaneTarget.classList.toggle(\"hidden\");\n }\n\n getPreview() {\n if (this.hasPreviewButtonTarget) {\n this.previewButtonTarget.disabled = true;\n }\n\n const formData = new FormData(this.formTarget);\n formData.delete(\"_method\");\n\n const showPreview = !this.previewPaneTarget.classList.contains(\"hidden\");\n\n post(this.urlValue, {\n query: {\n show_preview: showPreview,\n },\n body: formData,\n responseKind: \"turbo-stream\",\n });\n }\n}\n","import { ValueFormatterParams } from \"ag-grid-community\";\nimport { DataTypeDefinition } from \"ag-grid-enterprise\";\n\nconst numberFormatter = new Intl.NumberFormat(\"en-US\", {\n style: \"decimal\",\n maximumFractionDigits: 2,\n minimumFractionDigits: 2,\n});\n\nconst percentageFormatter = new Intl.NumberFormat(\"en-US\", {\n style: \"percent\",\n maximumFractionDigits: 2,\n minimumFractionDigits: 2,\n});\n\nexport const dataTypeDefinitions = {\n number: {\n baseDataType: \"number\",\n extendsDataType: \"number\",\n valueFormatter: (params: ValueFormatterParams) => {\n if (params.value == null) {\n return null;\n }\n\n return numberFormatter.format(params.value);\n },\n } as DataTypeDefinition,\n percentage: {\n baseDataType: \"number\",\n extendsDataType: \"number\",\n valueFormatter: (params: ValueFormatterParams) => {\n // for total rows the valueFormatter from the dataTypeDefinitions won't work as the rows have already been formatted.\n // Check the note at the end of this paragraph: https://www.ag-grid.com/javascript-data-grid/cell-data-types/#pre-defined-cell-data-types\n // in order for this to work we set a valueFormatter in the column definition and point it to this function.\n if (isNaN(params.value)) {\n return \"N/A\";\n } else {\n return percentageFormatter.format(params.value);\n }\n },\n } as DataTypeDefinition,\n dateString: {\n baseDataType: \"dateString\",\n extendsDataType: \"dateString\",\n valueFormatter: (params) => {\n if (params.value == null) {\n return null;\n }\n\n const dateParts = params.value.split(\"-\");\n\n if (dateParts.length === 3) {\n const date = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]));\n\n // Export date in the format: Mmm DD, YYYY\n return date.toLocaleDateString(\"en-US\", { year: \"numeric\", month: \"short\", day: \"2-digit\" });\n } else {\n return null;\n }\n },\n } as DataTypeDefinition,\n};\n\nexport const formatDateForDisplay = (date: string | Date | null): string => {\n return new Intl.DateTimeFormat(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n timeZone: \"UTC\",\n }).format(new Date(date));\n};\n","import { GridApi } from \"ag-grid-enterprise\";\nimport { post, Response } from \"@rails/request.js\";\n\nexport class CsvExporter {\n private gridApi: GridApi;\n\n constructor(gridApi: GridApi) {\n this.gridApi = gridApi;\n }\n\n private getDownloadPath(event: Event): string {\n return (event.currentTarget as HTMLButtonElement).form.action;\n }\n\n private prepareParams() {\n const filterModel = this.gridApi.getFilterModel();\n const sorting = this.gridApi.getColumnState();\n const sortObject = sorting.find((sort) => sort.sort !== null);\n const sortModel = sortObject ? [{ sort: sortObject.sort, colId: sortObject.colId }] : [];\n return { filterModel, sortModel };\n }\n\n private handleResponse(response: Response) {\n if (!response.ok) {\n throw new Error(`Network response was not ok: ${response.statusText}`);\n }\n return response.response.blob();\n }\n\n public exportCSV(event: Event, filename: string) {\n const button = event.currentTarget as HTMLButtonElement;\n const downloadPath = this.getDownloadPath(event);\n const params = this.prepareParams();\n\n button.disabled = true;\n\n post(downloadPath, {\n body: params,\n headers: { accept: \"text/csv\" },\n })\n .then(this.handleResponse)\n .then((blob: Blob) => {\n const url = window.URL.createObjectURL(blob);\n\n const a = document.createElement(\"a\");\n a.style.display = \"none\";\n a.href = url;\n\n const now = new Date();\n const formattedDate = now.toISOString().replace(/-|:|\\.\\d\\d\\d/g, \"\");\n a.download = `${filename}_${formattedDate}.csv`;\n\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n window.URL.revokeObjectURL(url);\n })\n .catch((error) => {\n console.error(\"Error exporting CSV:\", error);\n })\n .finally(() => {\n button.disabled = false;\n });\n }\n}\n","import { ICellRendererParams } from \"ag-grid-community\";\nimport { IAccountCode } from \"../../types/register\";\n\nexport function accountCodeRenderer(params: ICellRendererParams & { template: HTMLTemplateElement }) {\n const accountCode: IAccountCode = params.value;\n\n // If the row is grouped and the account code is missing, don't render anything\n if (params.node.group && !accountCode) {\n return null;\n }\n\n if (accountCode && accountCode.id) {\n const template = document.importNode(params.template.content, true);\n const div = template.querySelector(\"div\");\n\n div.textContent = accountCode.name;\n\n return div;\n } else {\n return `Uncoded`;\n }\n}\n\nexport function tagRenderer(params: ICellRendererParams & { template: HTMLTemplateElement }) {\n const tags = params.value || [];\n // Filtering out \"Untagged\" from the list here\n const realTags = tags.map((tag) => (tag.id ? tag : null)).filter(Boolean);\n const isGroupingByTag = params.colDef.colId === \"ag-Grid-AutoColumn\";\n\n // If the row is grouped, don't render anything\n if (params.node.group && !isGroupingByTag) {\n return null;\n }\n\n if (realTags && realTags.length > 0) {\n const parentEl = document.createElement(\"span\");\n parentEl.classList.add(\"space-x-1\");\n\n tags.forEach((tag) => {\n const template = document.importNode(params.template.content, true);\n const div = template.querySelector(\"div\");\n\n div.textContent = tag.name || \"Untagged\";\n\n if (tag.color_bg) {\n div.style.backgroundColor = tag.color_bg;\n div.style.color = tag.color_fg;\n }\n\n parentEl.appendChild(div);\n });\n\n return parentEl;\n } else {\n return `Untagged`;\n }\n}\n","import { FilterModel } from \"ag-grid-enterprise\";\n\nconst EMPTY_VALUE_FOR_SET_FILTER = \"__empty__\";\n\nfunction convertFilterModel(\n filterModel: FilterModel | null,\n from: null | string,\n to: null | string,\n): FilterModel | null {\n if (!filterModel) {\n return null;\n }\n\n return Object.keys(filterModel).reduce((acc, key) => {\n acc[key] = filterModel[key];\n\n if (filterModel[key]?.filterType === \"set\") {\n const values = filterModel[key].values;\n\n if (values.includes(from)) {\n values[values.indexOf(from)] = to;\n }\n\n filterModel[key].values = values;\n }\n\n return acc;\n }, {});\n}\n\n// When using a set filter on AG Grid, the grid uses null for \"empty\" values. Rails removes these values when POSTing to\n// the server, so we need to swap out the null with the custom value \"__empty__\".\nexport function convertFilterModelToServerSideFilterModel(filterModel: FilterModel | null): FilterModel | null {\n return convertFilterModel(filterModel, null, EMPTY_VALUE_FOR_SET_FILTER);\n}\n\nexport function convertServerSideFilterModelToFilterModel(filterModel: FilterModel | null): FilterModel | null {\n return convertFilterModel(filterModel, EMPTY_VALUE_FOR_SET_FILTER, null);\n}\n","import {\n IServerSideGetRowsRequest,\n IServerSideDatasource,\n IServerSideGetRowsParams,\n SetFilterValuesFuncParams,\n} from \"ag-grid-enterprise\";\nimport { convertFilterModelToServerSideFilterModel } from \"./set_filters\";\nimport { post, get } from \"@rails/request.js\";\nimport { IServerSideData } from \"../../types/register\";\n\nexport const createServerSideDatasource = (\n datasourceUrl: string,\n setLoadingState: (isLoading: boolean) => void,\n getCashFlowFilter: () => boolean,\n) => {\n return {\n getRows: (params: IServerSideGetRowsParams) => {\n const newRequest: IServerSideGetRowsRequest & { filterForCashFlow: boolean } = {\n ...params.request,\n filterForCashFlow: getCashFlowFilter(),\n };\n\n // When using a set filter, the grid uses null for \"empty\" values. Rails removes these values on the server\n // side, so we need to swap out the null with the custom value \"__empty__\"\n newRequest.filterModel = convertFilterModelToServerSideFilterModel(newRequest.filterModel);\n\n // For tags and tag groups, the grid sends an array of group keys, we need to flatten this to a single array.\n // If there is more than one group key in the original array, we should raise an error.\n newRequest.groupKeys.forEach((groupKey) => {\n if (Array.isArray(groupKey)) {\n if (groupKey.length > 1) {\n throw new Error(`Expected a single group key, got multiple: ${groupKey}`);\n }\n }\n });\n\n newRequest.groupKeys = newRequest.groupKeys.flat();\n\n setLoadingState(true);\n\n post(datasourceUrl, {\n body: { detailed_ledger_entry: newRequest },\n responseKind: \"json\",\n })\n .then((httpResponse) => httpResponse.json)\n .then((response: IServerSideData) => {\n params.success({\n rowData: response.rows,\n rowCount: response.lastRow,\n });\n })\n .finally(() => {\n setLoadingState(false);\n })\n .catch((error) => {\n console.error(error);\n params.fail();\n });\n },\n } as IServerSideDatasource;\n};\n\nexport const getFilterOptions = (url: string, params: SetFilterValuesFuncParams) => {\n const queryParams = new URLSearchParams();\n const filterColumn = params.colDef.field;\n\n queryParams.append(\"filter\", filterColumn);\n\n get(`${url}?${queryParams.toString()}`, { responseKind: \"json\" })\n .then((response) => response.json)\n .then((data) => {\n params.success(data.filter[filterColumn]);\n })\n .catch((error) => {\n console.error(error);\n });\n};\n","import { Controller } from \"@hotwired/stimulus\";\nimport {\n GetContextMenuItemsParams,\n GetRowIdParams,\n GridOptions,\n ToolPanelDef,\n createGrid,\n GridApi,\n KeyCreatorParams,\n ValueFormatterParams,\n SetFilterValuesFuncParams,\n CellDoubleClickedEvent,\n IRowNode,\n FilterModel,\n ColumnState,\n ProcessCellForExportParams,\n ProcessRowGroupForExportParams,\n IsServerSideGroupOpenByDefaultParams,\n GridState,\n} from \"ag-grid-enterprise\";\nimport { dataTypeDefinitions } from \"../helpers/reports/formatters\";\nimport { CsvExporter } from \"../helpers/register/csv_exporter\";\nimport { IDetailedLedgerEntry } from \"../types/register\";\nimport { accountCodeRenderer, tagRenderer } from \"../helpers/register/renderers\";\nimport { convertServerSideFilterModelToFilterModel } from \"../helpers/register/set_filters\";\nimport { createServerSideDatasource, getFilterOptions } from \"../helpers/register/server_side_datasource\";\nimport { isEqual } from \"lodash\";\n\nconst primaryKeyCreator = (params: KeyCreatorParams) => {\n return params.value.id;\n};\n\nconst objectValueFormatter = (params: ValueFormatterParams) => {\n return params.value.name;\n};\n\n// Connects to data-controller=\"advanced-register\"\nexport default class extends Controller {\n static targets = [\n \"grid\",\n \"accountCodeTemplate\",\n \"tagTemplate\",\n \"showLedgerTransactionButtonWrapper\",\n \"ledgerEntryCount\",\n \"clearSelectionButton\",\n \"bulkUpdateButton\",\n \"bulkEditErrors\",\n \"bulkUpdateModal\",\n \"ledgerEntryIdInputContainer\",\n \"ledgerEntryIdInputTemplate\",\n \"cashFlowAlert\",\n \"quickFilterDatepicker\",\n ];\n\n static values = {\n datasourceUrl: String,\n filtersUrl: String,\n selectedIds: Array,\n maxSelectableIds: {\n type: Number,\n default: 500,\n },\n isRowSelectionEnabled: {\n type: Boolean,\n default: true,\n },\n isGroupingByRows: {\n type: Boolean,\n default: false,\n },\n filterModel: {\n type: Object,\n default: {},\n },\n columnState: {\n type: Array,\n default: [],\n },\n expandedGroupIds: {\n type: Array,\n default: [],\n },\n // When we first show the grid, we still haven't loaded the data from the server, so the default here is true until\n // the grid is ready and we have loaded the data.\n gridIsLoading: {\n type: Boolean,\n default: true,\n },\n filterForCashFlow: {\n type: Boolean,\n default: false,\n },\n gridStateFromSavedView: {\n type: Object,\n default: {},\n },\n savedViewId: {\n type: String,\n default: \"\",\n },\n hasUnsavedChanges: {\n type: Boolean,\n default: false,\n },\n suppressChangedFilterFeedback: {\n type: Boolean,\n default: false,\n },\n };\n\n // Stimulus Values\n declare datasourceUrlValue: string;\n declare filtersUrlValue: string;\n declare selectedIdsValue: string[];\n declare maxSelectableIdsValue: number;\n declare isRowSelectionEnabledValue: boolean;\n declare isGroupingByRowsValue: boolean;\n declare filterModelValue: FilterModel;\n declare columnStateValue: ColumnState[];\n declare expandedGroupIdsValue: string[];\n declare gridIsLoadingValue: boolean;\n declare filterForCashFlowValue: boolean;\n declare gridStateFromSavedViewValue: GridState;\n declare savedViewIdValue: string;\n declare hasUnsavedChangesValue: boolean;\n declare suppressChangedFilterFeedbackValue: boolean;\n // Stimulus Targets\n declare gridTarget: HTMLDivElement;\n declare accountCodeTemplateTarget: HTMLTemplateElement;\n declare tagTemplateTarget: HTMLTemplateElement;\n declare hasShowLedgerTransactionButtonWrapperTarget: boolean;\n declare showLedgerTransactionButtonWrapperTarget: HTMLDivElement;\n declare hasCashFlowAlertTarget: boolean;\n declare cashFlowAlertTarget: HTMLDivElement;\n declare quickFilterDatepickerTarget: HTMLSelectElement;\n\n // Selecting rows and bulk update targets\n declare ledgerEntryCountTargets: HTMLSpanElement[];\n declare hasClearSelectionButtonTarget: boolean;\n declare clearSelectionButtonTarget: HTMLButtonElement;\n declare hasBulkUpdateButtonTarget: boolean;\n declare bulkUpdateButtonTarget: HTMLButtonElement;\n declare hasBulkUpdateModalTarget: boolean;\n declare bulkUpdateModalTarget: HTMLDialogElement;\n declare hasBulkEditErrorsTarget: boolean;\n declare bulkEditErrorsTarget: HTMLDivElement;\n declare ledgerEntryIdInputContainerTarget: HTMLDivElement;\n declare ledgerEntryIdInputTemplateTarget: HTMLTemplateElement;\n\n // Local Variables\n declare gridOptions: GridOptions;\n declare gridApi: GridApi;\n declare csvExporter: CsvExporter;\n\n // This flag is used to prevent updates to date filters from causing a feedback\n // loop that clears the filter when a quick filter date is selected\n declare preventResetFromClearingGridFilters: boolean;\n\n connect() {\n const defaultNumberColDef = {\n minWidth: 120,\n aggFunc: \"sum\",\n enableValue: true,\n allowedAggFuncs: [\"sum\"],\n filter: \"agNumberColumnFilter\",\n filterParams: {\n buttons: [\"reset\", \"apply\"],\n filterOptions: [\n \"equals\",\n \"notEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"inRange\",\n ],\n maxNumConditions: 1,\n },\n cellClass: [\"ag-right-aligned-cell\", \"font-mono\"],\n };\n\n const setFilterParams = {\n values: (params: SetFilterValuesFuncParams) => {\n getFilterOptions(this.filtersUrlValue, params);\n },\n keyCreator: primaryKeyCreator,\n valueFormatter: objectValueFormatter,\n refreshValuesOnOpen: true,\n buttons: [\"reset\", \"apply\"],\n closeOnApply: true,\n defaultToNothingSelected: true,\n suppressSorting: true,\n caseSensitive: true, // Required for prefix IDs to not clash with each other\n textFormatter: (value: string) => {\n // the `caseSensitive` option applies to the ids and the values, so in order to have case-insensitive\n // search in the drop down, we convert the value to lowercase\n return value.toLowerCase();\n },\n };\n\n const setFilterColDefWithTreeParams = {\n ...setFilterParams,\n treeList: true,\n treeListPathGetter: (value) => {\n return value?.treePath;\n },\n };\n\n this.gridOptions = {\n columnDefs: [\n {\n field: \"ledger\",\n headerName: \"Entity\",\n enableRowGroup: true,\n valueGetter: (params) => params.data?.ledger,\n valueFormatter: (params) => params.value?.name,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterParams },\n },\n {\n field: \"account\",\n headerName: \"Account\",\n enableRowGroup: true,\n valueGetter: (params) => params.data?.account,\n valueFormatter: (params) => params.value?.name,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterColDefWithTreeParams },\n },\n {\n field: \"effective_at\",\n headerName: \"Effective At\",\n minWidth: 140,\n cellClass: \"font-mono\",\n cellDataType: \"dateString\",\n sort: \"desc\",\n sortIndex: 0,\n filter: \"agDateColumnFilter\",\n filterParams: {\n browserDatePicker: true,\n buttons: [\"reset\", \"apply\"],\n closeOnApply: true,\n inRangeInclusive: true,\n filterOptions: [\n \"inRange\",\n \"lessThan\",\n {\n displayKey: \"lessThanOrEqual\",\n displayName: \"On or Before\",\n predicate: ([filterValue], cellValue) => cellValue <= filterValue,\n },\n \"greaterThan\",\n \"equals\",\n ],\n maxValidYear: \"2099\",\n minValidYear: \"1900\",\n maxNumConditions: 1,\n },\n },\n {\n field: \"debits\",\n headerName: \"Debits\",\n ...defaultNumberColDef,\n },\n {\n field: \"credits\",\n headerName: \"Credits\",\n ...defaultNumberColDef,\n },\n {\n field: \"accounting_amount\",\n headerName: \"Accounting Amount\",\n hide: true,\n ...defaultNumberColDef,\n },\n {\n field: \"description\",\n minWidth: 200,\n cellRenderer: (params) => {\n if (params.node.group) {\n return params.value;\n }\n\n if (params.value) {\n return `${params.value}`;\n } else {\n return `No description`;\n }\n },\n filter: \"agTextColumnFilter\",\n filterParams: {\n filterOptions: [\"contains\", \"notContains\", \"equals\", \"notEqual\", \"blank\", \"notBlank\"],\n buttons: [\"reset\", \"apply\"],\n maxNumConditions: 1,\n },\n },\n {\n field: \"account_code_group\",\n headerName: \"Account Code Group\",\n enableRowGroup: true,\n hide: true,\n cellRenderer: accountCodeRenderer,\n cellRendererParams: { template: this.accountCodeTemplateTarget },\n valueGetter: (params) => params.data?.account_code_group,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterParams },\n },\n {\n field: \"account_code\",\n headerName: \"Account Code\",\n enableRowGroup: true,\n cellRenderer: accountCodeRenderer,\n cellRendererParams: { template: this.accountCodeTemplateTarget },\n valueGetter: (params) => params.data?.account_code,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterColDefWithTreeParams },\n },\n {\n field: \"tag_groups\",\n headerName: \"Tag Groups\",\n enableRowGroup: true,\n cellRenderer: tagRenderer,\n cellRendererParams: { template: this.tagTemplateTarget },\n hide: true,\n sortable: false,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterParams },\n },\n {\n field: \"tags\",\n headerName: \"Tags\",\n enableRowGroup: true,\n cellRenderer: tagRenderer,\n cellRendererParams: { template: this.tagTemplateTarget },\n sortable: false,\n filter: \"agSetColumnFilter\",\n filterParams: { ...setFilterColDefWithTreeParams },\n },\n ],\n defaultColDef: { sortable: true, flex: 1 },\n autoGroupColumnDef: {\n minWidth: 200,\n sortable: false,\n cellRendererParams: {\n totalValueGetter: (params) => {\n return `Sub Total ${params.value.name}`;\n },\n },\n },\n allowContextMenuWithControlKey: true,\n getContextMenuItems: (params: GetContextMenuItemsParams) => {\n return params.defaultItems.filter((item) => item !== \"export\");\n },\n rowModelType: \"serverSide\",\n getRowId: (params: GetRowIdParams) => {\n // There's a lot going on here, essentially we're creating a unique identifier for the row.\n // When we're grouping by rows, we can pull the parent keys from the row node. We're concatenating the\n // parent keys and the data ID to create a unique identifier for the row. The id would be something like\n // \"ledger_123-acct_tmpl_456-le_789\" if we were grouping by ledgers, and then accounts.\n // When we're not grouping by rows, we rely on the data ID to create a unique identifier for the row.\n const objectIds: Set = new Set();\n\n // The parent keys can be an array of strings or objects (we're using objects most of the time via the value\n // getter on the column definition)\n (params.parentKeys || []).flat().forEach((key: string | { id: string }) => {\n if (typeof key === \"string\") {\n objectIds.add(key);\n } else if (typeof key === \"object\") {\n objectIds.add(key.id);\n }\n });\n\n if (params.data.id !== undefined && params.data.id !== null) {\n objectIds.add(params.data.id.toString());\n }\n\n const rowGroupCols = params.api.getRowGroupColumns();\n const thisGroupCol = rowGroupCols[params.level];\n\n // If we're grouping by rows, here we pull the keys from the parent nodes\n if (thisGroupCol) {\n let additionalData = params.data[thisGroupCol.getColDef().field];\n\n // Additional data can be an array of objects, so we need to check for that\n if (Array.isArray(additionalData)) {\n additionalData = { id: additionalData.map((item) => item.id).join(\"-\") };\n }\n\n if (additionalData) {\n const identifier = additionalData.id || additionalData?.name?.toLowerCase();\n\n objectIds.add(identifier);\n }\n }\n\n const uniqueKey = Array.from(objectIds).join(\"-\");\n\n return uniqueKey;\n },\n onCellDoubleClicked: (event: CellDoubleClickedEvent) => {\n if (this.hasShowLedgerTransactionButtonWrapperTarget) {\n const theButton = this.showLedgerTransactionButtonWrapperTarget.querySelector(\"button\");\n const cardData = JSON.parse(theButton?.getAttribute(\"data-card\") || \"{}\");\n const ledgerTransactionId = event.data?.ledger_transaction?.id;\n\n if (ledgerTransactionId) {\n cardData.turboSrc = `/ledger_management/ledger_transactions/${ledgerTransactionId}/modal_show`;\n theButton?.setAttribute(\"data-card\", JSON.stringify(cardData));\n\n theButton.click();\n } else {\n console.warn(\"No ledger transaction ID found for this row, could not show modal\");\n }\n } else {\n console.warn(\"No show ledger transaction button wrapper target found, could not show modal\");\n }\n },\n serverSideDatasource: createServerSideDatasource(\n this.datasourceUrlValue,\n this.setLoadingState.bind(this),\n this.getCashFlowFilter.bind(this),\n ),\n isServerSideGroupOpenByDefault: (params: IsServerSideGroupOpenByDefaultParams) => {\n return this.expandedGroupIdsValue.includes(params.rowNode.id);\n },\n dataTypeDefinitions: { ...dataTypeDefinitions },\n groupTotalRow: \"bottom\",\n rowGroupPanelShow: \"always\",\n sideBar: {\n toolPanels: [\n {\n id: \"columns\",\n labelDefault: \"Columns\",\n labelKey: \"columns\",\n iconKey: \"columns\",\n toolPanel: \"agColumnsToolPanel\",\n toolPanelParams: { suppressPivots: true, suppressPivotMode: true },\n },\n {\n id: \"filters\",\n labelDefault: \"Filters\",\n labelKey: \"filters\",\n iconKey: \"filter\",\n toolPanel: \"agFiltersToolPanel\",\n toolPanelParams: { suppressPivots: true, suppressPivotMode: true },\n },\n ] as ToolPanelDef[],\n },\n pivotMode: false,\n pivotPanelShow: \"never\",\n suppressServerSideFullWidthLoadingRow: true,\n // Row selection logic\n rowSelection: {\n mode: \"multiRow\",\n checkboxes: false,\n headerCheckbox: false,\n enableClickSelection: \"enableSelection\",\n isRowSelectable: (node: IRowNode) => {\n if (!this.isRowSelectionEnabledValue || this.isGroupingByRowsValue) {\n return false;\n }\n\n // Groups nodes are not selectable\n return !node.group;\n },\n },\n onSelectionChanged: (event) => {\n if (event.source === \"gridInitializing\") {\n return;\n }\n\n const nodeIds = (event.api.getServerSideSelectionState().toggledNodes || []) as string[];\n\n this.setSelectedIdsFromNodeIds(nodeIds);\n\n this.saveGridState(new Event(\"selectionChanged\"));\n },\n onRowGroupOpened: (event) => {\n const nodeId = event.node.id;\n const uniqueSetIds = new Set([...this.expandedGroupIdsValue, nodeId]);\n\n if (event.node.expanded) {\n uniqueSetIds.add(nodeId);\n } else {\n uniqueSetIds.delete(nodeId);\n }\n\n // While we're here, remove any nodes that don't exist in the grid\n uniqueSetIds.forEach((id) => {\n if (!event.api.getRowNode(id)) {\n uniqueSetIds.delete(id);\n }\n });\n\n this.expandedGroupIdsValue = Array.from(uniqueSetIds);\n },\n onColumnRowGroupChanged: (event) => {\n if (event.source === \"gridInitializing\") {\n return;\n }\n\n const groupingByRows = event.api.getRowGroupColumns().length !== 0;\n\n // Note we are deselecting all nodes here before setting the isGroupingByRowsValue value. We use the\n // isGroupingByRowsValue value to determine if the rows are selectable or not, and if we don't deselect\n // all nodes before setting the value, then the selection state cannot be changed.\n if (groupingByRows !== this.isGroupingByRowsValue) {\n event.api.deselectAll();\n\n this.isGroupingByRowsValue = groupingByRows;\n }\n\n this.saveGridState(new Event(\"columnRowGroupChanged\"));\n },\n onFilterChanged: (event) => {\n this.handleFilterChanged(event);\n this.saveGridState(new Event(\"filterChanged\"));\n },\n onSortChanged: (event) => {\n if (event.source === \"gridInitializing\") {\n return;\n }\n\n this.saveGridState(new Event(\"sortChanged\"));\n },\n onColumnVisible: (event) => {\n if (event.source === \"gridInitializing\") {\n return;\n }\n\n this.saveGridState(new Event(\"columnVisible\"));\n },\n onGridPreDestroyed: (_event) => {\n // The Grid is rarely destroyed in real use cases, but it is regularly destroyed and recreated when developing,\n // so we save it off here to make sure we don't lose the state.\n this.saveGridState(new Event(\"gridPreDestroyed\"));\n },\n onStateUpdated: (event) => {\n if (event.sources.includes(\"gridInitializing\") || !this.hasSavedView) {\n return;\n }\n\n this.hasUnsavedChangesValue = !this.currentGridStateIsEqualToSavedView();\n },\n onGridReady: (event) => {\n // Handle Grouping and Node Selection\n this.isGroupingByRowsValue = event.api.getRowGroupColumns().length !== 0;\n\n let savedState = JSON.parse(sessionStorage.getItem(\"registerState\") || \"{}\");\n let filterModelToApply: FilterModel | null = null;\n\n const nodeIds = (savedState?.rowSelection?.toggledNodes || []) as string[];\n\n this.setSelectedIdsFromNodeIds(nodeIds);\n\n if (this.selectedIdsValue.length === 0) {\n this.clearSelectedIds();\n } else {\n this.syncSelectedIdsWithGrid();\n }\n\n // If we're loading the grid from a Saved View, we don't want to apply the state from session storage as we\n // already have the state we want in the gridStateFromSavedViewValue property.\n if (this.hasSavedView) {\n savedState = {\n ...this.gridStateFromSavedViewValue,\n rowSelection: {\n toggledNodes: nodeIds,\n },\n };\n }\n\n if (this.filterModelValue && Object.keys(this.filterModelValue).length > 0) {\n filterModelToApply = this.filterModelValue;\n } else {\n filterModelToApply = savedState?.filter?.filterModel;\n }\n\n if (filterModelToApply) {\n event.api.setFilterModel(convertServerSideFilterModelToFilterModel(filterModelToApply));\n\n if (!this.hasSavedView) {\n // We remove the search params from the URL after applying the filter model because they were used\n // to build up the filter model in the first place on the server side, so we no longer need them here.\n // Currently this is used when redirected from a report view.\n history.replaceState(null, \"\", document.location.pathname);\n }\n }\n\n if (this.columnStateValue) {\n event.api.applyColumnState({\n state: this.columnStateValue,\n applyOrder: false,\n defaultState: null,\n });\n }\n },\n initialState: {\n ...this.gridStateFromSavedViewValue, // This is the state from a Saved View\n partialColumnState: true\n },\n };\n\n this.gridApi = createGrid(this.gridTarget, this.gridOptions);\n this.csvExporter = new CsvExporter(this.gridApi);\n }\n\n getGridState() {\n this.dispatch(\"get-grid-state\", {\n detail: {\n gridState: this.gridApi.getState(),\n period: this.quickFilterDatepickerTarget.value,\n },\n });\n }\n\n setCurrentGridStateAsSavedView() {\n if (this.hasSavedView) {\n this.gridStateFromSavedViewValue = this.gridApi.getState();\n this.hasUnsavedChangesValue = false;\n }\n }\n\n disconnect() {\n this.gridApi.destroy();\n }\n\n saveGridState(_event: Event) {\n this.filterModelValue = convertServerSideFilterModelToFilterModel(this.gridApi.getFilterModel());\n this.columnStateValue = this.gridApi.getColumnState().map((columnState: ColumnState) => {\n return {\n colId: columnState.colId,\n hide: columnState.hide,\n sort: columnState.sort,\n sortIndex: columnState.sortIndex,\n rowGroup: columnState.rowGroup,\n rowGroupIndex: columnState.rowGroupIndex,\n };\n });\n\n // Don't save the grid state in session storage if we're loading the grid from a Saved View\n if (this.hasSavedView) {\n return;\n }\n\n const currentState = this.getGridStateWithConvertedFilterModel();\n\n // The full grid state can be quite large, so we save it off in session storage.\n sessionStorage.setItem(\"registerState\", JSON.stringify(currentState));\n }\n\n currentGridStateIsEqualToSavedView(): boolean {\n const currentState = this.gridApi.getState();\n const savedViewState = this.gridStateFromSavedViewValue;\n\n const isFilterModelEqual: boolean = isEqual(currentState.filter?.filterModel, savedViewState.filter?.filterModel);\n\n const isSortEqual: boolean = isEqual(currentState.sort, savedViewState.sort);\n\n const isColumnVisibilityEqual: boolean = isEqual(currentState.columnVisibility, savedViewState.columnVisibility);\n\n const isRowGroupEqual: boolean = isEqual(currentState.rowGroup, savedViewState.rowGroup);\n\n const isColumnOrderEqual: boolean = isEqual(currentState.columnOrder, savedViewState.columnOrder);\n\n const isRowGroupExpansionEqual: boolean = isEqual(currentState.rowGroupExpansion, savedViewState.rowGroupExpansion);\n\n return (\n isFilterModelEqual &&\n isSortEqual &&\n isColumnVisibilityEqual &&\n isColumnOrderEqual &&\n isRowGroupEqual &&\n isRowGroupExpansionEqual\n );\n }\n\n // Gets the grid state with the filter model converted from the server-side filter model where empty set values are\n // represented as '__empty__' to the client-side filter model where they are represented as null.\n getGridStateWithConvertedFilterModel(): GridState {\n const currentState = this.gridApi.getState();\n\n if (currentState.filter?.filterModel) {\n currentState.filter.filterModel = convertServerSideFilterModelToFilterModel(currentState.filter.filterModel);\n }\n\n return currentState;\n }\n\n async applyDateRange(event: Event & { params: { startDate: string | null; endDate: string | null } }) {\n if (this.preventResetFromClearingGridFilters) {\n // Skip the logic if we are resetting the quick date filter but want to keep the current date filters\n // This happens when the user selects a quick filter and then manually changes the filter dates in the grid\n return;\n }\n\n const select = event.target as HTMLSelectElement;\n const selectedOption = select.options[select.selectedIndex];\n\n if (!selectedOption) {\n return;\n }\n\n const startDate = selectedOption.dataset.startDate;\n const endDate = selectedOption.dataset.endDate;\n\n if (!startDate && !endDate) {\n await this.gridApi.setColumnFilterModel(\"effective_at\", null);\n this.gridApi.onFilterChanged();\n\n return;\n }\n\n let filterModel = {};\n\n if (startDate && !endDate) {\n filterModel = {\n type: \"greaterThan\",\n dateFrom: startDate,\n };\n } else if (!startDate && endDate) {\n filterModel = {\n type: \"lessThan\",\n dateTo: endDate,\n };\n } else {\n filterModel = {\n type: \"inRange\",\n dateFrom: startDate,\n dateTo: endDate,\n };\n }\n\n await this.gridApi.setColumnFilterModel(\"effective_at\", filterModel);\n\n this.gridApi.onFilterChanged(\"quickFilter\");\n }\n\n resetFilters() {\n this.gridApi.setFilterModel(null);\n this.resetQuickDateFilter();\n sessionStorage.removeItem(\"registerState\");\n }\n\n resetQuickDateFilter() {\n this.dispatch(\"reset-quick-date-filter\");\n }\n\n handleFilterChanged(event) {\n // We are using the 'quickFilter' source to identify that the filter change is coming from a user-initiated quick filter selection\n // This is a workaround to prevent the grid from clearing the date filter when the user selects a quick date filter\n // The quickFilter source is an AG Grid feature, though, so we are co-opting the meaning for this use-case and may have to re-evaluate\n // if we wish to take advantage of the AG Grid quick filter feature in the future\n if (event.source === \"quickFilter\") {\n return;\n }\n\n const newFilterModel = this.gridApi.getFilterModel();\n const oldFilterModel = this.filterModelValue;\n const dateColumns = [\"effective_at\"];\n\n // Check if the date filter was removed\n const dateFilterRemoved = dateColumns.some((colId) => {\n const oldFilter = oldFilterModel[colId];\n const newFilter = newFilterModel[colId];\n return oldFilter && !newFilter;\n });\n\n // Check if the date filter has a different dateFrom or dateTo\n const dateFilterChanged = dateColumns.some((colId) => {\n const oldFilter = oldFilterModel[colId];\n const newFilter = newFilterModel[colId];\n return (\n oldFilter && newFilter && (oldFilter.dateFrom !== newFilter.dateFrom || oldFilter.dateTo !== newFilter.dateTo)\n );\n });\n\n if (dateFilterRemoved) {\n this.resetQuickDateFilter();\n } else if (dateFilterChanged) {\n this.preventResetFromClearingGridFilters = true;\n this.resetQuickDateFilter();\n this.preventResetFromClearingGridFilters = false;\n }\n }\n\n // This is our custom CSV export that exports all the data from the server\n exportCsvLineItems(event: Event) {\n this.csvExporter.exportCSV(event, \"advanced_register_export\");\n }\n\n // This is the native AG Grid Export that exports what is currently visible in the grid\n exportCsvView() {\n this.gridApi.exportDataAsCsv({\n /*\n * The processRowGroupCallback is invoked once per row group and returns a string to be\n * displayed in the group cell. Here we are handling adding indentations to the group cell\n * based on how nested the row group is. This callback is adapted from the default behavior\n * in the createValueForGroupNode in ag-grid-enterprise.js.\n */\n processRowGroupCallback: (params: ProcessRowGroupForExportParams) => {\n let node = params.node;\n const isFooter = node.footer;\n const breadcrumbIndentations = [];\n\n let key = node.key as { name: string } | { name: string }[] | string;\n\n if (key && typeof key === \"object\" && !Array.isArray(key)) {\n // Ledgers, accounts, and account codes are objects with a name property\n key = key.name;\n } else if (Array.isArray(key)) {\n // For tags and tag groups\n key = key.map((item) => item.name).join(\"; \");\n }\n\n while (node.parent) {\n node = node.parent;\n breadcrumbIndentations.push(\" \");\n }\n\n const groupValue = breadcrumbIndentations.concat(key).join(\" \");\n\n if (isFooter) {\n return `${groupValue} Sub Total`;\n } else {\n return groupValue;\n }\n },\n processCellCallback: (params: ProcessCellForExportParams) => {\n const field = params.column.getColDef().field;\n\n if ((field === \"tags\" || field === \"tag_groups\") && Array.isArray(params.value)) {\n return params.value.map((tag) => tag.name).join(\"; \");\n } else if (\n field === \"ledger\" ||\n field === \"account\" ||\n field === \"account_code\" ||\n field === \"account_code_group\"\n ) {\n return params.value?.name;\n } else {\n return params.value;\n }\n },\n });\n }\n\n isGroupingByRowsValueChanged(newValue: boolean, _oldValue: boolean) {\n if (newValue) {\n this.clearSelectedIds();\n }\n }\n\n selectedIdsValueChanged() {\n this.updateBulkUpdateButton();\n this.updateClearSelectionButton();\n this.updateBulkEditErrors();\n }\n\n filterForCashFlowValueChanged() {\n if (this.filterForCashFlowValue) {\n this.cashFlowAlertTarget.classList.remove(\"hidden\");\n } else {\n this.cashFlowAlertTarget.classList.add(\"hidden\");\n }\n }\n\n hasUnsavedChangesValueChanged(newValue: boolean, _oldValue: boolean) {\n if (this.suppressChangedFilterFeedbackValue || !this.hasSavedView) {\n return;\n }\n\n if (newValue) {\n this.dispatch(\"view-has-unsaved-changes\");\n } else {\n this.dispatch(\"view-has-no-unsaved-changes\");\n }\n }\n\n removeCashFlowFilter() {\n this.filterForCashFlowValue = false;\n\n this.gridApi.onFilterChanged();\n }\n\n updateBulkUpdateButton() {\n this.ledgerEntryCountTargets.forEach((ledgerEntryCountTarget) => {\n if (this.selectedIdsValue.length > 0) {\n ledgerEntryCountTarget.classList.remove(\"hidden\");\n ledgerEntryCountTarget.textContent = this.selectedIdsValue.length.toString();\n } else {\n ledgerEntryCountTarget.classList.add(\"hidden\");\n ledgerEntryCountTarget.textContent = \"\";\n }\n });\n\n if (this.hasBulkUpdateButtonTarget) {\n this.bulkUpdateButtonTarget.disabled =\n this.selectedIdsValue.length === 0 || this.selectedIdsValue.length > this.maxSelectableIdsValue;\n }\n }\n\n updateClearSelectionButton() {\n if (this.hasClearSelectionButtonTarget) {\n if (this.selectedIdsValue.length > 0) {\n this.clearSelectionButtonTarget.classList.remove(\"hidden\");\n } else {\n this.clearSelectionButtonTarget.classList.add(\"hidden\");\n }\n }\n }\n\n updateBulkEditErrors() {\n if (this.selectedIdsValue.length > this.maxSelectableIdsValue) {\n this.bulkEditErrorsTarget.classList.remove(\"hidden\");\n this.bulkEditErrorsTarget.querySelector(\"#bulk-edit-delta\")!.textContent = (\n this.selectedIdsValue.length - this.maxSelectableIdsValue\n ).toString();\n } else {\n this.bulkEditErrorsTarget.classList.add(\"hidden\");\n }\n }\n\n showBulkUpdateModal() {\n this.bulkUpdateModalTarget.showModal();\n }\n\n hideBulkUpdateModal() {\n this.bulkUpdateModalTarget.close();\n }\n\n bulkUpdateSubmit(event: Event) {\n event.preventDefault();\n\n const submitButton = event.currentTarget as HTMLButtonElement;\n submitButton.disabled = true;\n\n const form = submitButton.form as HTMLFormElement;\n\n // Clear the ledger entry id input container\n this.ledgerEntryIdInputContainerTarget.innerHTML = \"\";\n\n // Add the selected ledger entry ids to the form before submitting\n this.selectedIdsValue.forEach((id) => {\n const ledgerEntryIdInput = document.importNode(this.ledgerEntryIdInputTemplateTarget.content, true);\n const ledgerEntryIdInputEl = ledgerEntryIdInput.querySelector(\"input\");\n ledgerEntryIdInputEl.value = id.toString();\n\n this.ledgerEntryIdInputContainerTarget.appendChild(ledgerEntryIdInput);\n });\n\n form.requestSubmit();\n }\n\n clearSelectedIds() {\n if (this.gridApi) {\n this.gridApi.deselectAll();\n }\n }\n\n setSelectedIdsFromNodeIds(nodeIds: string[]) {\n this.selectedIdsValue =\n nodeIds\n .map((nodeId: string) => {\n // When restoring the state, AG Grid uses the node ID instead of the ID we need to actually update\n // the ledger entries. So we only return the node ID if it's a ledger entry ID.\n if (nodeId?.startsWith(\"le_\")) {\n return nodeId;\n } else {\n return null;\n }\n })\n .filter((id: string | null) => id !== null) || [];\n }\n\n syncSelectedIdsWithGrid() {\n this.gridApi.setServerSideSelectionState({\n selectAll: false,\n toggledNodes: this.selectedIdsValue,\n });\n }\n\n setLoadingState(isLoading: boolean) {\n this.gridIsLoadingValue = isLoading;\n }\n\n getCashFlowFilter() {\n return this.filterForCashFlowValue;\n }\n\n get hasSavedView() {\n return this.savedViewIdValue !== \"\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { destroy } from \"@rails/request.js\";\n\n// Connects to data-controller=\"attachment-delete\"\nexport default class extends Controller {\n static values = {\n url: String,\n entityId: { type: Number, default: null }\n };\n\n declare urlValue: string;\n declare entityIdValue: number;\n\n deleteAttachment(event: Event) {\n if (!(confirm(\"Are you sure you want to delete this attachment?\"))) {\n event.preventDefault();\n event.stopImmediatePropagation();\n } else {\n destroy(\n this.urlValue,\n {\n body: JSON.stringify({\n entity_id: this.entityIdValue\n }),\n responseKind: \"turbo-stream\",\n }\n ).then((_response) => {\n this.element.closest('li').remove();\n });\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static values = { target: String }\n\n declare targetValue: string;\n declare hasTargetValue: boolean;\n\n connect() {\n if (this.hasTargetValue) {\n document.getElementById(this.targetValue).click();\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { Turbo } from \"@hotwired/turbo-rails\";\n\n// Connects to data-controller=\"auto-reload\"\nexport default class extends Controller {\n static values = {\n interval: { type: Number, default: 5000 },\n active: { type: Boolean, default: true },\n };\n\n declare intervalValue: number;\n declare activeValue: boolean;\n\n declare reloadTimer: NodeJS.Timeout;\n\n connect() {\n if (this.activeValue) {\n this.startAutoReload();\n }\n }\n\n disconnect() {\n this.stopAutoReload();\n }\n\n startAutoReload() {\n this.reloadTimer = setInterval(() => {\n this.reloadPage();\n }, this.intervalValue);\n }\n\n stopAutoReload() {\n if (this.reloadTimer) {\n clearInterval(this.reloadTimer);\n }\n }\n\n reloadPage() {\n Turbo.visit(window.location.href);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static values = {\n delay: Number,\n };\n\n static targets = [\"input\"];\n\n declare timeout: number | null;\n declare delayValue: number;\n declare inputTarget: HTMLInputElement | HTMLTextAreaElement;\n declare initialValue: string;\n\n initialize(): void {\n this.timeout = null;\n }\n\n connect(): void {\n this.initialValue = this.inputTarget.value;\n }\n\n save(): void {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n\n // Only save if the value has actually changed\n if (this.inputTarget.value !== this.initialValue) {\n this.timeout = window.setTimeout(() => {\n this.dispatch(\"saving\");\n const form = this.element as HTMLFormElement;\n form.requestSubmit();\n // Update the initial value after saving\n this.initialValue = this.inputTarget.value;\n }, this.delayValue);\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"autohide\"\nexport default class extends Controller {\n static values = {\n delay: Number,\n class: String,\n };\n\n declare delayValue: number;\n declare classValue: string;\n\n connect() {\n setTimeout(() => {\n this.element.classList.add(...this.classValue.split(\" \"));\n setTimeout(() => {\n this.element.classList.add(\"hidden\");\n this.element.remove();\n }, 500);\n }, this.delayValue || 5000);\n }\n\n reconnect() {\n this.disconnect();\n this.connect();\n }\n}\n","import { Controller } from '@hotwired/stimulus';\nimport { get } from '@rails/request.js';\nimport * as Turbo from \"@hotwired/turbo\";\n\n// Connects to data-controller=\"bank-register\"\nexport default class extends Controller {\n static targets = [\"accountSelect\", \"ledgerSelect\", \"dateSelect\", \"search\", \"startDate\", \"endDate\"];\n\n static values = {\n url: String\n };\n\n declare accountSelectTarget: HTMLSelectElement;\n declare ledgerSelectTarget: HTMLSelectElement;\n declare dateSelectTarget: HTMLSelectElement;\n declare hasDateSelectTarget: boolean;\n declare startDateTarget: HTMLInputElement;\n declare hasStartDateTarget: boolean;\n declare endDateTarget: HTMLInputElement;\n declare hasEndDateTarget: boolean;\n declare searchTarget: HTMLInputElement;\n declare hasSearchTarget: boolean;\n declare urlValue: string;\n\n ledgerChanged(_event: Event) {\n this.updateTargetStreamsRequest([\n \"bank_register_add_transaction\",\n \"bank_register_account_options\",\n \"bank_register_date_filter\",\n \"bank_register_search\",\n \"bank_register_export\",\n \"bank_register_account_balance\",\n \"bank_register_entries\"\n ]);\n }\n\n accountChanged(_event: Event) {\n this.updateTargetStreamsRequest();\n }\n\n dateChanged(_event: Event) {\n this.updateTargetStreamsRequest([\"bank_register_export\",\"bank_register_account_balance\", \"bank_register_entries\"]);\n }\n\n searchChanged(_event: Event) {\n this.updateTargetStreamsRequest([\"bank_register_export\",\"bank_register_entries\"]);\n }\n\n updateTargetStreamsRequest(targetStreams: string[] = [\n \"bank_register_add_transaction\",\n \"bank_register_date_filter\",\n \"bank_register_search\",\n \"bank_register_export\",\n \"bank_register_account_balance\",\n \"bank_register_entries\"\n ]) {\n const selectedLedgerId = this.ledgerSelectTarget.selectedOptions[0].value;\n const selectedAccountId = this.accountSelectTarget.selectedOptions[0].value;\n\n let searchQuery = \"\";\n if (this.hasSearchTarget) {\n searchQuery = this.searchTarget.value;\n }\n\n let startDate = \"\";\n if (this.hasStartDateTarget) {\n startDate = this.startDateTarget.value;\n }\n\n let endDate = \"\";\n if (this.hasEndDateTarget) {\n endDate = this.endDateTarget.value;\n }\n\n let selectedDateRange = \"\";\n if (this.hasDateSelectTarget) {\n selectedDateRange = this.dateSelectTarget.selectedOptions[0].value;\n if(selectedDateRange === \"Custom\" && startDate === \"\" && endDate === \"\") {\n return;\n }\n }\n\n const query = {\n ledger_id: selectedLedgerId,\n account_id: selectedAccountId,\n q: searchQuery,\n date_range: selectedDateRange,\n start_date: startDate,\n end_date: endDate\n }\n\n const targetStreamsQueryString = targetStreams.map(stream => `target_streams[]=${encodeURIComponent(stream)}`).join('&');\n const fullQueryString = `${new URLSearchParams(query).toString()}&${targetStreamsQueryString}`;\n\n get(`${this.urlValue}?${fullQueryString}`, {\n responseKind: \"turbo-stream\",\n }).then((response) => {\n const newUrl = response?.response?.url;\n\n if (newUrl) {\n const [baseUrl, queryParams] = newUrl.split('?');\n const htmlUrl = `${baseUrl.endsWith('.html') ? baseUrl : baseUrl + '.html'}${queryParams ? '?' + queryParams : ''}`;\n history.pushState({}, \"\", htmlUrl);\n Turbo.navigator.history.push(new URL(htmlUrl));\n }\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"bank-transaction\"\nexport default class extends Controller {\n declare accountTargets: HTMLSelectElement[];\n declare destinationAccountSelectTargets: HTMLSelectElement[];\n declare amountValue: number;\n declare creditsTargets: HTMLInputElement[];\n declare debitsTargets: HTMLInputElement[];\n declare rowPositionTargets: HTMLElement[];\n declare rowTargets: HTMLElement[];\n declare rowTemplateTarget: HTMLTemplateElement;\n declare submitTarget: HTMLInputElement;\n declare targetTarget: HTMLButtonElement;\n declare multiLedgerTransactionTarget: HTMLElement;\n\n static targets = [\n \"account\",\n \"destinationAccountSelect\",\n \"credits\",\n \"debits\",\n \"row\",\n \"rowPosition\",\n \"rowTemplate\",\n \"submit\",\n \"target\",\n \"multiLedgerTransaction\",\n ];\n\n static values = {\n amount: Number,\n };\n\n connect() {\n this.initializeDestinationAccountSelectsAmounts();\n }\n\n initializeDestinationAccountSelectsAmounts() {\n this.destinationAccountSelectTargets.forEach( (select) => {\n if (select.value) {\n this.setAmountWithRow(select.closest(\"[data-bank-transaction-target='row']\"));\n }\n });\n }\n\n multiLedgerTransactionTargetConnected() {\n this.validate();\n }\n\n disableSubmit() {\n this.submitTarget.disabled = true;\n }\n\n add() {\n const content = this.rowTemplateTarget.innerHTML.replace(/NEW_RECORD/g, new Date().getTime().toString());\n\n this.targetTarget.insertAdjacentHTML(\"beforebegin\", content);\n this.validate();\n }\n\n remove(event) {\n const row = event.target.closest(\"[data-bank-transaction-target='row']\");\n row.style.display = \"none\";\n this.dispatch(\"handleUpdates\");\n row.remove();\n this.validate();\n }\n\n setAmount(event) {\n const row = event.target.closest(\"[data-bank-transaction-target='row']\");\n this.setAmountWithRow(row);\n }\n\n setAmountWithRow(row) {\n const initialDebitsValue = parseFloat(this.debitsTargets[0].value);\n const initialCreditsValue = parseFloat(this.creditsTargets[0].value);\n\n if (initialDebitsValue > 0) {\n const creditsTotal = this.sumInputAmounts(this.creditsTargets);\n const remainingCreditsAmount = Math.max(initialDebitsValue - creditsTotal, 0).toFixed(2);\n const rowCreditsTarget = row.querySelector(\"[data-bank-transaction-target='credits']\");\n if (this.cleanseCurrency(rowCreditsTarget.value) == 0) {\n rowCreditsTarget.value = this.formatCurrency(remainingCreditsAmount);\n rowCreditsTarget.dispatchEvent(new Event('input', { bubbles: true }));\n }\n } else if (initialCreditsValue > 0) {\n const debitsTotal = this.sumInputAmounts(this.debitsTargets);\n const remainingDebitsAmount = Math.max(initialCreditsValue - parseFloat(debitsTotal), 0).toFixed(2);\n const rowDebitsTarget = row.querySelector(\"[data-bank-transaction-target='debits']\");\n\n if (this.cleanseCurrency(rowDebitsTarget.value) == 0) {\n rowDebitsTarget.value = this.formatCurrency(remainingDebitsAmount);\n rowDebitsTarget.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n\n this.dispatch(\"handleUpdates\");\n }\n\n sumInputAmounts(inputTargets) {\n return inputTargets.reduce((sum, input) => {\n if (!isNaN(this.cleanseCurrency(input.value))) {\n sum += this.cleanseCurrency(input.value);\n }\n return sum;\n }, 0);\n }\n\n validate() {\n const accountsHaveValues = this.accountTargets.every((account) => account.value !== \"\");\n const debitsAreNumbers = this.debitsTargets.every((input) => !isNaN(this.cleanseCurrency(input.value)));\n const creditsAreNumbers = this.creditsTargets.every((input) => !isNaN(this.cleanseCurrency(input.value)));\n\n if (accountsHaveValues && debitsAreNumbers && creditsAreNumbers) {\n const creditsTotal = this.sumInputAmounts(this.creditsTargets).toFixed(2);\n const debitsTotal = this.sumInputAmounts(this.debitsTargets).toFixed(2);\n const debitsEqualCredits = debitsTotal === creditsTotal;\n\n if (debitsEqualCredits) {\n this.submitTarget.disabled = false;\n } else {\n this.disableSubmit();\n }\n } else {\n this.disableSubmit();\n }\n }\n\n formatCurrency(amount: string) {\n const formattedValue = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n }).format(parseFloat(amount));\n\n return formattedValue;\n }\n\n cleanseCurrency(amount: string) {\n return parseFloat(amount.replace(/^0+|[^0-9.]/g, ''));\n }\n}\n","import { RowNode } from \"ag-grid-enterprise\";\n\n// A section header is a root-level row that is a group header like \"Assets\" or \"Expenses\"\nexport function isSectionHeader(node: RowNode): boolean {\n const isRootLevel = node.level === 0;\n\n return isRootLevel && isGroupHeader(node);\n}\n\nexport function isSectionFooter(node: RowNode): boolean {\n const isRootLevel = node.level === 0;\n\n return isRootLevel && isGroupFooter(node);\n}\n\n// A group header is a row that is a group header for an account with sub-accounts like\n// \"Cash\" or \"Accounts Receivable\"\nexport function isGroupHeader(node: RowNode): boolean {\n return (node.group || node.hasChildren()) && !node.footer;\n}\n\nexport function isGroupFooter(node: RowNode): boolean {\n return (node.group || node.hasChildren()) && node.footer;\n}\n","import {\n ICellRendererComp,\n ICellRendererParams,\n IHeaderGroupComp,\n IHeaderGroupParams,\n RowNode,\n} from \"ag-grid-enterprise\";\nimport { ITag, ITagGroup, IAccountCode, IAccountCodeGroup, IFlattenedTagOrAccountCode } from \"../../types\";\nimport { isGroupHeader } from \"./node_helpers\";\n\nexport const accountCodeStyledCell = (value: string, bgColor: string, fgColor: string) => {\n return `\n
\n ${value}\n
\n `;\n};\n\nconst tagStyledCell = (value: string, bgColor: string, fgColor: string) => {\n let extraClasses = \"\";\n if (value === \"Untagged\") {\n bgColor = \"#e6e6e8\";\n fgColor = \"#6A6A6A\";\n extraClasses = \"italic\";\n }\n return `\n
\n ${value}\n
\n `;\n};\n\nexport class FlattenedAccountCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n let metadata = params.data?.metadata;\n if (!metadata && params.context) {\n metadata = params.context.metadata;\n }\n\n const accountCode: IAccountCode | undefined = metadata?.accountCode;\n const accountCodeGroup: IAccountCodeGroup | undefined = metadata?.accountCodeGroup;\n\n let accountCodeName = \"\";\n let template = \"\";\n const value = params.value ? params.value : params.node?.key;\n\n if (accountCode && accountCodeGroup) {\n if (accountCodeGroup.name === \"Uncoded\") {\n accountCodeName = accountCode.name;\n template = accountCodeStyledCell(accountCode.name, accountCode.accountCodeBg, accountCode.accountCodeFg);\n } else {\n accountCodeName = `${accountCodeGroup.name}: ${accountCode.name}`;\n template = accountCodeStyledCell(accountCodeName, accountCode.accountCodeBg, accountCode.accountCodeFg);\n }\n }\n\n // Remove the account code name from the value\n const accountName = value?.replace(`- ${accountCodeName}`, \"\");\n const accountSpan = `${accountName}`;\n\n if (params.data?.groupLink) {\n this.eGui.innerHTML = `${accountSpan} ${template}`;\n } else {\n this.eGui.innerHTML = `${accountSpan} ${template}`;\n }\n\n // Handle grand total case\n if (params.node.footer && params.node.level === -1) {\n this.eGui.innerHTML = `Grand Total`;\n }\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class AccountCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n // gets called once before the renderer is used\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\"); // create the cell\n\n let template: string;\n const value = params.value ? params.value : params.node?.key;\n\n let metadata = params.node?.data?.metadata;\n if (!metadata && params.context) {\n metadata = params.context.metadata;\n }\n\n if (metadata?.generated_total_row) {\n template = `${value}`;\n } else if (params.node.footer) {\n const isRootLevel = params.node.level === -1;\n\n if (isRootLevel) {\n template = `Grand Total`;\n } else {\n template = `Total ${value}`;\n }\n } else {\n const tag: ITag | undefined = metadata?.tag;\n const accountCode: IAccountCode | undefined = metadata?.accountCode;\n\n if (tag) {\n template = tagStyledCell(tag.name, tag.tagBg, tag.tagFg);\n } else if (accountCode) {\n template = accountCodeStyledCell(accountCode.name, accountCode.accountCodeBg, accountCode.accountCodeFg);\n } else if (!params.data || params.node.allChildrenCount !== null) {\n // No data means this is a \"filler\" or \"non-provided\" row or has no children (which means it's a row group when using tree mode)\n let metadata = undefined;\n let tagGroup: ITagGroup | undefined = undefined;\n let accountCodeGroup: IAccountCodeGroup | undefined = undefined;\n\n params.node.childrenAfterFilter.forEach((child) => {\n tagGroup = child.data?.metadata?.tagGroup as ITagGroup;\n accountCodeGroup = child.data?.metadata?.accountCodeGroup as IAccountCodeGroup;\n\n if (child.data?.metadata) {\n metadata = child.data.metadata;\n return;\n }\n });\n\n if (metadata && value && tagGroup?.name === value) {\n template = tagStyledCell(metadata.tagGroup.name, metadata.tag.tagBg, metadata.tag.tagFg);\n } else if (metadata && value && accountCodeGroup?.name === value) {\n template = accountCodeStyledCell(\n metadata.accountCodeGroup.name,\n metadata.accountCode.accountCodeBg,\n metadata.accountCode.accountCodeFg,\n );\n } else {\n template = value;\n }\n }\n }\n\n if (template === undefined) {\n template = value;\n }\n\n template = params.data?.groupLink\n ? `${template}`\n : template;\n\n this.eGui.innerHTML = template;\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class GLAccountCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n // gets called once before the renderer is used\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n let template: string;\n const value = params.value;\n\n if (value === undefined) {\n return;\n }\n\n if (params.node.footer) {\n const isRootLevel = params.node.level === -1;\n const isAccountLevel = params.node.level === 1;\n\n if (isRootLevel) {\n template = `Grand Total`;\n } else if (isAccountLevel) {\n template = `Total ${value}`;\n } else {\n template = `Total ${value}`;\n }\n } else {\n template = `${value}`;\n }\n\n if (template === undefined) {\n template = params.value;\n }\n\n this.eGui.innerHTML = template;\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class GLCellRenderer implements ICellRendererComp {\n eGui!: HTMLSpanElement;\n\n // gets called once before the renderer is used\n init(params: ICellRendererParams) {\n // create the cell\n this.eGui = document.createElement(\"span\");\n const value = params.value;\n const formattedValue = params.valueFormatted;\n const node = params.node as unknown as RowNode;\n\n if (params.node.level === 0) {\n this.eGui.innerHTML = \"\";\n return;\n }\n\n if ((isGroupHeader(node) && node.expanded) || value === null) {\n this.eGui.innerHTML = \"\";\n return;\n }\n\n if (value === undefined) {\n return;\n }\n\n const link = this.getLink(params);\n\n if (link) {\n this.eGui.innerHTML = `${formattedValue}`;\n } else {\n if (value === \"No description\") {\n this.eGui.innerHTML = `${value}`;\n } else if (formattedValue) {\n this.eGui.innerHTML = `${formattedValue}`;\n } else {\n this.eGui.innerHTML = `${value}`;\n }\n }\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n\n getLink(params: ICellRendererParams): string | false {\n const linkField = `${params.colDef.field}_link`;\n\n if (params.data && params.data[linkField]) {\n return params.data[linkField];\n }\n\n if (params.colDef.colId == \"total\" && params.data && params.data.groupLink) {\n return params.data.groupLink;\n }\n\n return false;\n }\n}\n\nexport class NumberCellRenderer implements ICellRendererComp {\n eGui!: HTMLSpanElement;\n\n // gets called once before the renderer is used\n init(params: ICellRendererParams) {\n // create the cell\n this.eGui = document.createElement(\"span\");\n const value = params.value;\n const formattedValue = params.valueFormatted;\n const node = params.node as unknown as RowNode;\n\n if (params.node?.data?.metadata?.generated_total_row) {\n if (value === null) {\n this.eGui.innerHTML = \"\";\n } else {\n this.eGui.innerHTML = `${formattedValue}`;\n }\n return;\n }\n\n if ((isGroupHeader(node) && node.expanded) || value === null) {\n this.eGui.innerHTML = \"\";\n return;\n }\n\n if (value === undefined) {\n return;\n }\n\n const link = this.getLink(params);\n\n if (link) {\n this.eGui.innerHTML = `${formattedValue}`;\n } else {\n this.eGui.innerHTML = formattedValue;\n }\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n\n getLink(params: ICellRendererParams): string | false {\n const linkField = `${params.colDef.field}_link`;\n\n if (params.data && params.data[linkField]) {\n return params.data[linkField];\n }\n\n if (params.colDef.colId == \"total\" && params.data && params.data.groupLink) {\n return params.data.groupLink;\n }\n\n return false;\n }\n}\n\nexport function tagStyledHeader(value, bgColor, fgColor) {\n let extraClasses = \"\";\n if (value === \"Untagged\") {\n bgColor = \"#c7c7c9\";\n fgColor = \"#4a4949\";\n extraClasses = \"italic\";\n }\n return `\n
\n ${value}\n
\n `;\n}\n\nexport class HeaderGroupRenderer implements IHeaderGroupComp {\n eGui!: HTMLDivElement;\n\n // gets called once before the renderer is used\n init(params) {\n this.eGui = document.createElement(\"div\");\n const colDef = params.columnGroup.getColGroupDef();\n\n let metadata = colDef?.metadata;\n if (!metadata && colDef?.context) {\n metadata = colDef?.context.metadata;\n }\n\n let content;\n if (metadata?.tag_id) {\n content = tagStyledHeader(params.displayName, metadata?.tag_color_bg, metadata?.tag_color_fg);\n } else {\n content = `${params.displayName}`;\n }\n\n this.eGui.innerHTML = `\n
\n ${content}\n
\n `;\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: IHeaderGroupParams) {\n return false;\n }\n}\n\nexport function tagHeaderTemplate(colDef, isTextHeader = false) {\n let content;\n const metadata = colDef?.metadata;\n\n if ((metadata?.tag_id && !isTextHeader) || colDef.headerName === \"Untagged\") {\n content = tagStyledHeader(colDef.headerName, metadata?.tag_color_bg, metadata?.tag_color_fg);\n } else {\n content = `${colDef.headerName}`;\n }\n\n return headerTemplate(content);\n}\n\nexport function consolidatedHeaderTemplate(colDef) {\n let content;\n const metadata = colDef?.metadata;\n\n if (colDef?.metadata?.consolidationMetadata) {\n const spans = Object.entries(metadata?.consolidationMetadata).map(\n ([_key, consolidationMetadata]: [string, { text: string; value: string }]) => {\n return `${consolidationMetadata.text}: ${consolidationMetadata.value}`;\n },\n );\n\n content = `${colDef.headerName}\n
${spans.join(\"
\")}\n `;\n } else {\n content = `${colDef.headerName}`;\n }\n\n return headerTemplate(content);\n}\n\nexport class AccountCodeCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n const accountCode: IFlattenedTagOrAccountCode | undefined = params.data?.accountCode;\n\n let template = \"\";\n if (accountCode) {\n const accountCodeName = `${accountCode.group}: ${accountCode.name}`;\n template = accountCodeStyledCell(accountCodeName, accountCode.colorBg, accountCode.colorFg);\n }\n\n this.eGui.innerHTML = template;\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class TagCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n const tags: IFlattenedTagOrAccountCode[] | undefined = params.data?.tags;\n\n let template = \"\";\n if (tags) {\n tags.forEach((tag) => {\n const tagName = `${tag.group}: ${tag.name}`;\n\n let colorBg = tag.colorBg;\n if (tag.colorBg === null) {\n colorBg = \"#BDBDBD\";\n }\n\n let colorFg = tag.colorFg;\n if (tag.colorFg === null) {\n colorFg = \"#6A6A6A\";\n }\n\n template += tagStyledCell(tagName, colorBg, colorFg);\n });\n }\n\n this.eGui.innerHTML = template;\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport function headerTemplate(content) {\n return `\n
\n \n
\n \n \n \n \n ${content}\n \n
\n
\n `;\n}\n","import {\n ICellRendererParams,\n} from \"ag-grid-enterprise\";\n\n// Define budget groups for variance coloring\nexport const POSITIVE_VARIANCE_GROUPS = ['Revenues', 'Sources of Cash'];\nexport const POSITIVE_VARIANCE_TOTALS = ['Total Revenues', 'Total Sources of Cash', 'Net Income'];\nexport const NEGATIVE_VARIANCE_GROUPS = ['Expenses', 'Uses of Cash'];\nexport const NEGATIVE_VARIANCE_TOTALS = ['Total Expenses', 'Total Uses of Cash'];\n\n/**\n * Gets the appropriate CSS class for coloring variance values in the UI\n *\n * For positive groups (Revenues/Sources):\n * - Positive variance (actual > budget) is good → green\n * - Negative variance (actual < budget) is bad → red\n *\n * For negative groups (Expenses/Uses):\n * - Negative variance (actual < budget) is good → green\n * - Positive variance (actual > budget) is bad → red\n */\nexport function determineVarianceColor(\n data: { budget_group?: string, name?: string },\n field: string | undefined, // e.g., \"Jan.variance_amount\"\n value: string | number | null | undefined\n): string | null {\n if (value === null || value === undefined || Number.isNaN(Number(value)) || Number(value) === 0) {\n return null;\n }\n\n if (!field) {\n return null;\n }\n\n const budgetGroup = data.budget_group;\n const name = data.name;\n\n const isPositiveGroup =\n (budgetGroup && POSITIVE_VARIANCE_GROUPS.includes(budgetGroup)) ||\n (name && POSITIVE_VARIANCE_TOTALS.includes(name));\n\n const isInDefinedGroup = isPositiveGroup ||\n (budgetGroup && NEGATIVE_VARIANCE_GROUPS.includes(budgetGroup)) ||\n (name && NEGATIVE_VARIANCE_TOTALS.includes(name));\n\n if (!isInDefinedGroup) {\n return null;\n }\n\n const isPercentage = field.includes('variance_percentage');\n const period = field.split('.')[0];\n const periodData = data[period];\n\n const valueForColor = getValueForVarianceColoring(Number(value), isPercentage, periodData);\n const isGood = isGoodVariance(valueForColor, isPositiveGroup);\n\n return isGood ? 'text-green-500' : 'text-red-500';\n}\n\n// For positive groups: positive variance is good\n// For negative groups: negative variance is good\nexport function isGoodVariance(value: number, isPositiveGroup: boolean): boolean {\n return isPositiveGroup ? value > 0 : value < 0;\n}\n\nexport function getValueForVarianceColoring(\n value: number,\n isPercentage: boolean,\n periodData: { budget?: number, variance_amount?: number } | undefined\n): number {\n // If not a percentage or no period data, use the original value\n if (!isPercentage || !periodData) {\n return value;\n }\n\n // Special case for variance percentage with negative budget\n const budget = periodData.budget;\n const varianceAmount = periodData.variance_amount;\n\n if (budget !== undefined && budget < 0 &&\n varianceAmount !== undefined && !isNaN(varianceAmount)) {\n return varianceAmount;\n }\n\n return value;\n}\n\nexport function getVarianceColorClass(params: ICellRendererParams): string | null {\n if (!params.data) {\n return null;\n }\n\n return determineVarianceColor(params.data, params.colDef.field, params.value) as string | null;\n}\n","import {\n ICellRendererComp,\n ICellRendererParams,\n} from \"ag-grid-enterprise\";\nimport { getVarianceColorClass } from \"./variance_helpers\";\n\nexport class ActualCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n const field = params.colDef.field; // e.g. \"Jan.actual\"\n const period = field.split(\".\")[0]; // e.g. \"Jan\"\n const url_path = params.data[period].actual_url_path; // e.g. \"/ledger_management/detailed_ledger_entries\"\n \n if (url_path) {\n this.eGui.innerHTML = `${params.valueFormatted}`;\n } else {\n this.eGui.innerHTML = params.valueFormatted;\n }\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class BudgetCellRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n const field = params.colDef.field; // e.g. \"Jan.actual\"\n const period = field.split(\".\")[0]; // e.g. \"Jan\"\n const url_path = params.data[period].budget_url_path; // e.g. \"/budget_management/budget/:id?auto_click_id=:auto_click_id\"\n\n if (url_path) {\n this.eGui.innerHTML = `${params.valueFormatted}`;\n } else {\n this.eGui.innerHTML = params.valueFormatted;\n }\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\n// Base class for variance renderers\nabstract class BaseVarianceRenderer implements ICellRendererComp {\n eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams) {\n this.eGui = document.createElement(\"div\");\n\n // Allow subclasses to perform custom initialization\n this.initContent(params);\n\n const colorClass = getVarianceColorClass(params);\n if (colorClass) {\n this.eGui.classList.add(colorClass);\n }\n }\n\n // Abstract method to be implemented by subclasses\n abstract initContent(params: ICellRendererParams): void;\n\n getGui() {\n return this.eGui;\n }\n\n refresh(_params: ICellRendererParams) {\n return false;\n }\n}\n\nexport class VariancePercentageCellRenderer extends BaseVarianceRenderer {\n initContent(params: ICellRendererParams): void {\n // Check if we should display N/A\n const field = params.colDef.field; // e.g. \"Jan.variance_percentage\"\n if (field) {\n const period = field.split(\".\")[0]; // e.g. \"Jan\"\n const hasBudget = params.data[period]?.budget != null && !isNaN(params.data[period]?.budget);\n\n if (isNaN(params.value) && hasBudget) {\n this.eGui.innerHTML = \"N/A\";\n return;\n }\n }\n\n if (params.value === null || params.value === undefined || isNaN(params.value)) {\n this.eGui.innerHTML = '';\n } else {\n this.eGui.innerHTML = `${(params.value * 100).toFixed(2)}%`;\n }\n }\n}\n\nexport class VarianceAmountCellRenderer extends BaseVarianceRenderer {\n initContent(params: ICellRendererParams): void {\n this.eGui.innerHTML = params.valueFormatted;\n }\n}\n","import { ExcelRow, ExcelStyle, ProcessCellForExportParams } from \"ag-grid-enterprise\";\nimport { formatDateForDisplay } from \"../reports/formatters\";\n\nexport const defaultExcelExportParams = {\n headerRowHeight: params => {\n // the 10th row is the header row (e.g., \"Budget\", \"Actuals\", etc.) below the group header (e.g, \"JAN\", \"FEB\", etc.)\n if (params.rowIndex == 10) {\n return 30;\n } else {\n return 19;\n }\n },\n processHeaderCallback: params => {\n if (params.column.getColId() === 'name') {\n return \"Account\";\n } else {\n return params.column.getColDef().headerName;\n }\n },\n processRowGroupCallback: params => {\n return params.node.key;\n }\n}\n\nexport function excelStyles(): ExcelStyle[] {\n return [\n {\n id: 'budget-analysis-header',\n dataType: 'String',\n font: {\n bold: true,\n size: 18\n }\n },\n {\n id: \"header\",\n interior: {\n pattern: \"Solid\",\n color: \"#015965\",\n },\n font: {\n size: 14,\n color: \"#ffffff\",\n },\n alignment: {\n vertical: \"Center\",\n }\n },\n {\n id: \"number-cell\",\n dataType: \"Number\",\n numberFormat: {\n format: \"#,##0.00\",\n },\n },\n {\n id: \"percentage-cell\",\n alignment: {\n horizontal: \"Right\"\n },\n numberFormat: {\n format: \"###,##0.00%\",\n },\n },\n {\n id: 'section',\n interior: {\n pattern: \"Solid\",\n color: \"#e5e7eb\"\n },\n font: {\n bold: true,\n size: 13\n },\n },\n {\n id: \"subtotal\",\n borders: {\n borderTop: {\n color: \"black\",\n lineStyle: \"Continuous\",\n weight: 1,\n },\n },\n font: {\n bold: true,\n size: 13,\n },\n },\n {\n id: \"text-green-500\",\n font: {\n color: \"#0e9f6e\",\n },\n },\n {\n id: \"text-red-500\",\n font: {\n color: \"#f05252\",\n },\n },\n ]\n}\n\nexport function headerCells({ header, period, ledgers }): ExcelRow[] {\n return [\n { cells: [] },\n { cells: [{ data: { value: header, type: 'String' }, styleId: 'budget-analysis-header' }] },\n { cells: [{ data: { value: `Generated on ${formatDateForDisplay(new Date())}`, type: 'String' } }] },\n { cells: [{ data: { value: period, type: 'String'} }] },\n { cells: [{ data: { value: ledgers, type: 'String'} }] },\n { cells: [] },\n { cells: [] },\n { cells: [] }\n ];\n}\n\nexport const excelFileDetails = {\n fileName: `budget-analysis-${new Date().toISOString().replace(/:/g, \"-\")}.xlsx`,\n author: \"SumIt Software, Inc.\",\n sheetName: \"budget_analysis\",\n}\n\n// Process cell callback for Excel export to handle indentation and format special values\nexport function processCellForExcel(params: ProcessCellForExportParams): string {\n if (!params.column?.getColDef().field || !params.node?.data) {\n return String(params.value ?? '');\n }\n\n const field = params.column.getColDef().field;\n\n if (field === 'name') {\n return formatNameColumn(params);\n }\n\n if (field.includes('variance_percentage')) {\n return formatVariancePercentage(params);\n }\n\n return String(params.value ?? '');\n}\n\nfunction formatNameColumn(params: ProcessCellForExportParams): string {\n const data = params.node.data;\n const needsIndent = data?.type === 'account' || data?.type === 'account_code';\n\n return (needsIndent && data.nested_level > 0)\n ? addIndentation(params.value, data.nested_level)\n : String(params.value ?? '');\n}\n\nfunction formatVariancePercentage(params: ProcessCellForExportParams): string {\n return shouldShowNA(params.value) ? 'N/A' : String(params.value ?? '');\n}\n\nfunction shouldShowNA(value: string | number | null | undefined): boolean {\n return value === null ||\n value === undefined ||\n Number.isNaN(Number(value));\n}\n\nfunction addIndentation(value: string | number | null | undefined, nestedLevel: number): string {\n const indent = ' '.repeat(nestedLevel);\n return indent + (value ?? '');\n}\n","import { Controller, ActionEvent } from \"@hotwired/stimulus\";\nimport {\n ColDef,\n ColGroupDef,\n createGrid,\n GridApi,\n GridOptions,\n InitialGroupOrderComparatorParams,\n GetContextMenuItemsParams,\n} from \"ag-grid-enterprise\";\nimport { dataTypeDefinitions } from \"../helpers/reports/formatters\";\nimport { IBudgetAnalysisVariance, IBudgetAnalysisRowData } from \"../types/budget_analysis\";\nimport { accountCodeStyledCell } from \"../helpers/reports/renderers\";\nimport {\n ActualCellRenderer,\n BudgetCellRenderer,\n VarianceAmountCellRenderer,\n VariancePercentageCellRenderer\n} from \"../helpers/budget_analysis/renderers\";\nimport {\n defaultExcelExportParams,\n excelFileDetails,\n excelStyles,\n headerCells,\n processCellForExcel\n} from \"../helpers/budget_analysis/excel_options\";\nimport { determineVarianceColor } from \"../helpers/budget_analysis/variance_helpers\";\n\nconst nestedLevelClasses = {\n 1: \"pl-8\",\n 2: \"pl-16\",\n 3: \"pl-24\",\n 4: \"pl-32\",\n 5: \"pl-40\"\n}\n\nexport default class extends Controller {\n static values = {\n rowData: Array,\n columnDefs: Array,\n completedPeriodColumns: Array,\n budgetType: String\n };\n\n static targets = [\"grid\", \"option\"];\n\n // Stimulus Values\n declare columnDefsValue: (ColGroupDef & { children: ColDef[] })[];\n declare completedPeriodColumnsValue: string[];\n declare rowDataValue: IBudgetAnalysisRowData[];\n declare hasRowDataValue: boolean;\n declare budgetTypeValue: string;\n\n // Stimulus Targets\n declare gridTarget: HTMLDivElement;\n declare optionTargets: HTMLInputElement[];\n\n // Local Variables\n declare gridApi: GridApi;\n declare gridOptions: GridOptions;\n\n connect() {\n if (this.hasRowDataValue) {\n this.gridOptions = {\n autoSizeStrategy: {\n type: 'fitCellContents'\n },\n columnDefs: [\n { field: \"budget_group\", rowGroup: true, hide: true },\n {\n field: \"name\",\n pinned: \"left\",\n cellClass: params => {\n const classes = [];\n const type = params.node?.data?.type;\n\n if (type === \"subtotal\") {\n classes.push(\"subtotal\");\n }\n\n if (params.node.group || type === \"total\") {\n classes.push(\"section\");\n }\n\n return classes;\n },\n headerName: \"\",\n suppressSpanHeaderHeight: true,\n resizable: true,\n width: 380,\n cellRenderer: params => {\n if (params.data.type === 'account') {\n const eDiv = this.createNestedDiv(params.data.nested_level);\n eDiv.innerHTML = params.value;\n\n return eDiv;\n } else if (params.data.type === 'account_code') {\n const eDiv = this.createNestedDiv(params.data.nested_level, { defaultLevel: 2 });\n eDiv.innerHTML = accountCodeStyledCell(params.value, \"#E1EFFE\", \"#6A6A6A\").replace(/\\s+/g, ' ').trim();\n\n return eDiv;\n } else {\n return params.value;\n }\n }\n },\n ...this.columnDefsValue,\n ],\n components: {\n actualCellRenderer: ActualCellRenderer,\n budgetCellRenderer: BudgetCellRenderer,\n variancePercentageCellRenderer: VariancePercentageCellRenderer,\n varianceAmountCellRenderer: VarianceAmountCellRenderer\n },\n dataTypeDefinitions: {\n ...dataTypeDefinitions\n },\n defaultColDef: {\n resizable: false,\n sortable: false,\n width: 132,\n minWidth: 132,\n suppressHeaderMenuButton: true,\n suppressMovable: true,\n headerClass: \"bg-gray-100 !text-gray-800 font-medium\",\n cellClass: this.defaultColDefCellClass,\n },\n defaultColGroupDef: {\n headerClass: \"bg-sumit-primary-cyan-700\",\n },\n defaultExcelExportParams: defaultExcelExportParams,\n excelStyles: excelStyles(),\n initialGroupOrderComparator: (params: InitialGroupOrderComparatorParams) => {\n const order = this.budgetTypeValue === 'cash_flow' \n ? [ // Cash Flow order\n 'Beginning Balance',\n 'Total Beginning Balance', \n 'Sources of Cash',\n 'Total Sources of Cash',\n 'Uses of Cash',\n 'Total Uses of Cash',\n 'Ending Balance',\n 'Total Ending Balance'\n ]\n : [ // Net Income order\n 'Revenues',\n 'Total Revenues',\n 'Expenses', \n 'Total Expenses',\n 'Net Income'\n ];\n\n const nodeAValue = params.nodeA.key || params.nodeA?.data?.name;\n const nodeBValue = params.nodeB.key || params.nodeB?.data?.name;\n\n return order.indexOf(nodeAValue) - order.indexOf(nodeBValue);\n },\n groupAllowUnbalanced: true,\n groupDefaultExpanded: 1,\n groupDisplayType: 'groupRows',\n groupRowRendererParams: {\n suppressCount: true,\n },\n rowData: this.rowDataValue,\n onGridReady: () => {\n this.toggleAccountCategories();\n this.toggleCompletedPeriods();\n this.toggleVarianceAmount();\n this.toggleVariancePercentage();\n this.toggleRemainingBudget();\n this.toggleProjection();\n },\n getContextMenuItems: (_params: GetContextMenuItemsParams) => {\n const result = [\n \"autoSizeAll\",\n \"expandAll\",\n \"contractAll\",\n \"copy\",\n \"copyWithHeaders\",\n \"copyWithGroupHeaders\",\n ];\n return result;\n }\n };\n this.gridApi = createGrid(this.gridTarget, this.gridOptions);\n }\n }\n\n createNestedDiv(level: number, { defaultLevel = 1 }: { defaultLevel?: number } = {}): HTMLDivElement {\n const eDiv = document.createElement('div');\n \n if (this.isOptionChecked(\"show_account_categories\")) {\n eDiv.classList.add(nestedLevelClasses[level]);\n } else {\n eDiv.classList.add(nestedLevelClasses[defaultLevel]);\n }\n\n return eDiv;\n }\n\n defaultColDefCellClass(params) {\n const classes = [\"text-right\"];\n const type = params.node?.data?.type;\n const field = params.colDef.field;\n const cellDataType = params.colDef.cellDataType;\n const data = params.node.data;\n\n if (params.node.group || type === \"total\") {\n classes.push(\"section\");\n }\n\n if (type === \"subtotal\") {\n classes.push(\"subtotal\");\n }\n\n if (cellDataType === \"number\") {\n classes.push(\"number-cell\");\n }\n\n if (cellDataType === \"percentage\") {\n classes.push(\"percentage-cell\");\n }\n\n if (field.includes('variance_amount')) {\n const varianceColor = determineVarianceColor(data, field, params.value);\n\n if (varianceColor === 'text-green-500') {\n classes.push(\"text-green-500\");\n } else if (varianceColor === 'text-red-500') {\n classes.push(\"text-red-500\");\n }\n }\n\n if (field.includes('variance_percentage')) {\n const varianceColor = determineVarianceColor(data, field, params.value);\n\n if (varianceColor === 'text-green-500') {\n classes.push(\"text-green-500\");\n } else if (varianceColor === 'text-red-500') {\n classes.push(\"text-red-500\");\n }\n }\n\n return classes;\n }\n\n export(event: ActionEvent) {\n event.preventDefault();\n\n const { header, period, ledgers } = event.params;\n\n this.gridApi.exportDataAsExcel({\n prependContent: headerCells({ header, period, ledgers }),\n processCellCallback: processCellForExcel,\n ...excelFileDetails\n });\n }\n\n toggleAccountCategories() {\n if (this.isOptionChecked(\"show_account_categories\")) {\n this.gridApi.setGridOption('rowData', this.rowDataValue);\n } else {\n this.gridApi.setGridOption('rowData', this.rowDataValue.filter(row => !('postable' in row) || row.postable));\n }\n }\n\n toggleCompletedPeriods() {\n let columns = this.completedPeriodColumnsValue;\n\n if (this.isOptionChecked(\"show_completed_periods\")) {\n columns = this.filterVarianceColumns(columns);\n \n this.gridApi.setColumnsVisible(columns, true);\n } else {\n this.gridApi.setColumnsVisible(columns, false);\n }\n\n this.gridApi.autoSizeAllColumns();\n }\n\n toggleVarianceAmount() {\n const showVarianceAmount = this.isOptionChecked(\"show_variance_amount\");\n let columns = this.getChildColumnsByField(\"variance_amount\");\n\n if (showVarianceAmount && columns.length > 0) {\n if (!this.isOptionChecked(\"show_completed_periods\")) {\n columns = columns.filter(column => !this.completedPeriodColumnsValue.includes(column));\n }\n this.gridApi.setColumnsVisible(columns, true);\n } else if (!showVarianceAmount && columns.length > 0) {\n this.gridApi.setColumnsVisible(columns, false);\n }\n\n this.gridApi.autoSizeAllColumns();\n }\n\n toggleVariancePercentage() {\n const showVariancePercentage = this.isOptionChecked(\"show_variance_percentage\");\n let columns = this.getChildColumnsByField(\"variance_percentage\");\n\n if (showVariancePercentage && columns.length > 0) {\n if (!this.isOptionChecked(\"show_completed_periods\")) {\n columns = columns.filter(column => !this.completedPeriodColumnsValue.includes(column));\n }\n this.gridApi.setColumnsVisible(columns, true);\n } else if (!showVariancePercentage && columns.length > 0) {\n this.gridApi.setColumnsVisible(columns, false);\n }\n\n this.gridApi.autoSizeAllColumns();\n }\n\n toggleRemainingBudget() {\n const remainingBudgetColumns = this.getChildColumnsByField(\"remaining\")\n\n if (this.isOptionChecked(\"show_remaining_budget\")) {\n this.gridApi.setColumnsVisible(remainingBudgetColumns, true);\n } else {\n this.gridApi.setColumnsVisible(remainingBudgetColumns, false);\n }\n\n this.gridApi.autoSizeAllColumns();\n }\n\n toggleProjection() {\n let columns = this.getChildColumnsByField(\"projection\")\n\n if (this.isOptionChecked(\"show_projection\")) {\n columns = this.filterVarianceColumns(columns);\n\n this.gridApi.setColumnsVisible(columns, true);\n } else {\n this.gridApi.setColumnsVisible(columns, false);\n }\n\n this.gridApi.autoSizeAllColumns();\n }\n\n filterVarianceColumns(columns: string[]): string[] {\n columns = this.filterVarianceColumnsByType(columns, \"variance_amount\");\n columns = this.filterVarianceColumnsByType(columns, \"variance_percentage\");\n\n return columns;\n }\n\n filterVarianceColumnsByType(columns: string[], columnType: string): string[] {\n return this.isOptionChecked(`show_${columnType}`) ? columns : columns.filter(column => !column.includes(columnType));\n }\n\n getChildColumnsByField(fieldName: string): string[] {\n return this.columnDefsValue\n .flatMap(columnDef => columnDef.children)\n .filter(column => column.field.includes(fieldName))\n .map(column => column.field);\n }\n\n isOptionChecked(name: string): boolean {\n return this.optionTargets.find((option) => option.name === name).checked;\n }\n}\n","import StimulusFlatpickr from \"stimulus-flatpickr\";\nimport { Instance } from \"flatpickr/dist/types/instance\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\ntype DispatchOptions = Partial<{\n target: Element | Window | Document;\n detail: object;\n prefix: string;\n bubbles: boolean;\n cancelable: boolean;\n}>;\n\nexport default class extends StimulusFlatpickr {\n declare fp: Instance;\n declare actualsEndDateTarget: TomInput;\n declare dispatch: (eventName: string, options?: DispatchOptions) => CustomEvent;\n\n static targets = [\"actualsEndDate\"]\n\n // Hook fired when calendar is closed\n close(selectedDates, dateStr, _instance) { \n if (!Object.values(this.actualsEndDateTarget.tomselect.options).map(x => x.value).includes(dateStr)) {\n this.actualsEndDateTarget.tomselect.addOption({ value: dateStr, text: this.fp.formatDate(selectedDates[0], \"n/j/Y\") }, true);\n }\n\n this.actualsEndDateTarget.tomselect.setValue(dateStr);\n this.dispatch(\"submit\");\n }\n\n // Action invoked when tomselect option is selected\n input({ target: { value } }) {\n if (value == \"custom\") {\n this.fp.open();\n } else {\n this.dispatch(\"submit\");\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport tippy, { Instance as TippyInstance } from \"tippy.js\";\n\nexport default class extends Controller {\n static targets = [\"tooltipContent\"];\n\n declare tippy: TippyInstance;\n declare tooltipContentTarget: HTMLTemplateElement;\n\n connect() {\n this.tippy = tippy(this.element, {\n content: this.tooltipContentTarget.innerHTML,\n placement: \"bottom\",\n allowHTML: true,\n });\n }\n\n disconnect() {\n this.tippy.destroy();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n/**\n * Budget Table Sticky Controller\n * \n * This controller creates a clone of the table header row that sticks to the top of the viewport\n * when scrolling down. It maintains precise alignment with the underlying table and handles\n * horizontal scrolling while keeping certain columns fixed.\n * \n * Features:\n * - Configurable number of sticky columns (default: 2)\n * - Precise width matching between original and cloned cells\n * - Proper handling of horizontal scrolling\n * - Automatic recalculation on window resize\n * - Focus management to ensure active elements remain visible\n *\n * Usage:\n *
\n *
\n * \n *
\n * \n *
\n */\nexport default class extends Controller {\n static targets = [\"table\", \"headerRow\"];\n static values = {\n stickyColumnsCount: { type: Number, default: 2 } // Default to 2 sticky columns\n };\n\n declare tableTarget: HTMLElement;\n declare headerRowTarget: HTMLElement;\n declare stickyColumnsCountValue: number;\n \n // DOM references\n private headerClone: HTMLElement | null = null;\n \n // Measurements and state\n private isHeaderSticky: boolean = false;\n private tableOffset: number = 0;\n private headerHeight: number = 0;\n private cellWidths: number[] = [];\n\n // Performance optimizations\n private scrollThrottleId: number | null = null;\n\n // Observers\n private resizeObserver: ResizeObserver;\n private activeElementObserver: IntersectionObserver | null = null;\n\n // LIFECYCLE METHODS\n \n connect() {\n this.updateAllMeasurements();\n this.createHeaderClone();\n this.setupEventListeners();\n this.setupObservers();\n \n this.checkScrollPositionAndUpdateCloneVisibility();\n }\n\n disconnect() {\n this.removeEventListeners();\n this.removeObservers();\n this.removeHeaderClone();\n }\n\n reconnect() {\n this.disconnect();\n this.connect();\n }\n\n private setupEventListeners() {\n window.addEventListener(\"scroll\", this.handleScroll.bind(this));\n this.tableTarget.addEventListener(\"scroll\", this.handleTableScroll.bind(this));\n this.tableTarget.addEventListener(\"focusin\", this.handleFocusInsideTable.bind(this));\n }\n\n private removeEventListeners() {\n window.removeEventListener(\"scroll\", this.handleScroll);\n this.tableTarget.removeEventListener(\"scroll\", this.handleTableScroll);\n this.tableTarget.removeEventListener(\"focusin\", this.handleFocusInsideTable);\n }\n\n private setupObservers() {\n // Set up resize observer to recalculate positions if table dimensions change\n this.resizeObserver = new ResizeObserver(() => {\n this.updateAllMeasurements();\n this.removeHeaderClone();\n this.createHeaderClone();\n\n // Check if we should be showing the clone\n this.checkScrollPositionAndUpdateCloneVisibility();\n });\n \n this.resizeObserver.observe(this.tableTarget);\n this.resizeObserver.observe(this.headerRowTarget);\n \n // Set up observers for focus/click inside the table\n this.setupActiveElementObserver();\n }\n \n private removeObservers() {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n \n if (this.activeElementObserver) {\n this.activeElementObserver.disconnect();\n }\n \n if (this.scrollThrottleId) {\n window.clearTimeout(this.scrollThrottleId);\n this.scrollThrottleId = null;\n }\n }\n\n private removeHeaderClone() {\n if (this.headerClone && this.headerClone.parentElement) {\n this.headerClone.parentElement.removeChild(this.headerClone);\n }\n\n this.headerClone = null;\n }\n\n // Determines if an element is obscured by the sticky header\n private isElementObscuredByHeader(element: Element): boolean {\n const elementRect = element.getBoundingClientRect();\n\n // An element is obscured if:\n // 1. It's above the viewport (negative top)\n // 2. It's below the header but partially covered by it\n return (\n elementRect.top < 0 ||\n (elementRect.top < this.headerHeight && elementRect.bottom > 0)\n );\n }\n\n handleFocusInsideTable() {\n if (!this.isHeaderSticky || !this.activeElementObserver) return;\n \n // When an element receives focus, observe it\n const activeElement = document.activeElement;\n if (activeElement && this.tableTarget.contains(activeElement)) {\n this.activeElementObserver.observe(activeElement);\n \n if (this.isElementObscuredByHeader(activeElement)) {\n this.scrollActiveElementIntoView(activeElement);\n }\n }\n }\n \n // Scroll an obscured element into view below the sticky header\n private scrollActiveElementIntoView(element: Element) {\n const elementRect = element.getBoundingClientRect();\n const currentScrollY = window.scrollY;\n const newScrollY = currentScrollY + (elementRect.top - this.headerHeight - 10);\n \n window.scrollTo({\n top: newScrollY,\n behavior: 'smooth'\n });\n }\n \n // MEASUREMENT METHODS\n\n // Update all measurements including table position, header height, and cell widths\n private updateAllMeasurements() {\n const tableRect = this.tableTarget.getBoundingClientRect();\n this.tableOffset = tableRect.top + window.scrollY;\n this.headerHeight = this.headerRowTarget.offsetHeight;\n\n // Reset and capture all cell widths in a single array\n this.cellWidths = [];\n\n const headerCells = this.getHeaderCells(this.headerRowTarget);\n headerCells.forEach((cell: HTMLElement) => {\n this.cellWidths.push(cell.offsetWidth);\n });\n\n // Update the clone's height if it exists\n if (this.headerClone) {\n this.headerClone.style.height = `${this.headerHeight}px`;\n }\n\n // Update the observer rootMargin based on header height\n if (this.activeElementObserver) {\n this.activeElementObserver.disconnect();\n this.setupActiveElementObserver();\n }\n }\n\n // CELL SELECTION HELPERS\n\n // Gets header cells from a row element\n private getHeaderCells(rowElement: HTMLElement): HTMLElement[] {\n return Array.from(rowElement.querySelectorAll('.table-cell, .table-header-cell')) as HTMLElement[];\n }\n\n // Gets cells that should be sticky based on index\n private getStickyColumnCells(rowElement: HTMLElement): HTMLElement[] {\n const cells = this.getHeaderCells(rowElement);\n return cells.slice(0, this.stickyColumnsCountValue);\n }\n\n // Gets cells that should scroll horizontally (non-sticky)\n private getNonStickyColumnCells(rowElement: HTMLElement): HTMLElement[] {\n const cells = this.getHeaderCells(rowElement);\n return cells.slice(this.stickyColumnsCountValue);\n }\n\n // Calculates the left position for a sticky column based on its index\n private getStickyColumnLeftPosition(columnIndex: number): number {\n let leftPosition = 0;\n\n // Sum the widths of all previous columns\n for (let i = 0; i < columnIndex; i++) {\n leftPosition += this.cellWidths[i] || 0;\n }\n\n return leftPosition;\n }\n\n private tableContainer(): HTMLElement | null {\n return this.tableTarget.closest('.budget-table-container') || this.tableTarget.parentElement;\n }\n\n // CLONE MANAGEMENT\n\n // Creates a clone of the header row for sticky positioning\n private createHeaderClone() {\n this.headerClone = this.headerRowTarget.cloneNode(true) as HTMLElement;\n \n const tableContainer = this.tableContainer();\n const containerRect = tableContainer ? tableContainer.getBoundingClientRect() : this.tableTarget.getBoundingClientRect();\n \n this.applyBaseCloneStyles(containerRect);\n \n // Explicitly set styles for sticky columns\n this.setupStickyColumnsInClone();\n \n document.body.appendChild(this.headerClone);\n \n // Update cell widths to match the original exactly\n this.updateCloneCellWidths();\n \n // Initially hidden\n this.headerClone.style.display = \"none\";\n }\n \n private applyBaseCloneStyles(containerRect: DOMRect) {\n if (!this.headerClone) return;\n\n // Position and dimensions\n this.headerClone.style.position = \"fixed\";\n this.headerClone.style.top = \"0\";\n this.headerClone.style.left = `${containerRect.left}px`;\n this.headerClone.style.width = `${containerRect.width}px`;\n this.headerClone.style.height = `${this.headerRowTarget.offsetHeight}px`;\n\n // Appearance\n this.headerClone.style.backgroundColor = \"white\";\n this.headerClone.style.borderRight = \"1px solid rgb(229, 231, 235)\";\n this.headerClone.style.boxShadow = '0px 5px 3px rgba(0,0,0,0.05)';\n\n // Behavior\n this.headerClone.style.zIndex = \"100\";\n this.headerClone.style.display = \"none\";\n this.headerClone.style.overflow = \"hidden\";\n\n // Identifier\n this.headerClone.classList.add(\"header-clone\");\n }\n\n private setupStickyColumnsInClone() {\n if (!this.headerClone) return;\n \n const stickyCells = this.getStickyColumnCells(this.headerClone);\n \n stickyCells.forEach((cell, index) => {\n const leftPosition = this.getStickyColumnLeftPosition(index);\n \n cell.style.position = 'sticky';\n cell.style.left = `${leftPosition}px`;\n cell.style.zIndex = '20';\n cell.style.backgroundColor = 'white';\n cell.style.width = `${this.cellWidths[index]}px`;\n cell.style.minWidth = `${this.cellWidths[index]}px`;\n cell.style.boxSizing = 'border-box';\n });\n }\n \n // Updates cell widths in the clone to match the original\n private updateCloneCellWidths() {\n if (!this.headerClone) return;\n \n // Ensure cells in the clone have the exact same width as the original\n const cloneCells = this.getHeaderCells(this.headerClone);\n const originalCells = this.getHeaderCells(this.headerRowTarget);\n \n // First check if cell counts match\n if (cloneCells.length === originalCells.length && cloneCells.length === this.cellWidths.length) {\n cloneCells.forEach((cell: HTMLElement, index: number) => {\n cell.style.width = `${this.cellWidths[index]}px`;\n cell.style.minWidth = `${this.cellWidths[index]}px`;\n cell.style.boxSizing = 'border-box';\n });\n } else {\n // If counts don't match, recreate the clone\n this.removeHeaderClone();\n this.createHeaderClone();\n }\n \n // Refresh sticky columns\n this.setupStickyColumnsInClone();\n }\n \n // EVENT HANDLERS\n\n private checkScrollPositionAndUpdateCloneVisibility() {\n const scrollTop = window.scrollY;\n const shouldBeSticky = scrollTop > this.tableOffset;\n \n this.isHeaderSticky = shouldBeSticky;\n this.toggleCloneVisibility(shouldBeSticky);\n \n if (this.isHeaderSticky && this.headerClone) {\n this.updateClonePosition();\n }\n }\n\n // Handle vertical scrolling to show/hide sticky header\n private handleScroll = () => {\n // Throttle scroll events for better performance\n if (this.scrollThrottleId) {\n return;\n }\n \n this.scrollThrottleId = window.setTimeout(() => {\n this.checkScrollPositionAndUpdateCloneVisibility();\n this.scrollThrottleId = null;\n }, 10); // Short delay for smooth scrolling\n }\n \n // Handle horizontal scrolling of the table to adjust clone position\n private handleTableScroll = () => {\n if (this.isHeaderSticky && this.headerClone) {\n this.updateCloneHorizontalPosition();\n }\n }\n \n private toggleCloneVisibility(visible: boolean) {\n if (!this.headerClone) return;\n \n if (visible) {\n this.headerClone.style.display = \"flex\";\n this.updateClonePosition();\n } else {\n this.headerClone.style.display = \"none\";\n }\n }\n \n private updateClonePosition() {\n if (!this.headerClone) return;\n \n const tableContainer = this.tableContainer();\n \n if (tableContainer) {\n // Get the exact position of the container\n const containerRect = tableContainer.getBoundingClientRect();\n \n // Update clone position to match container exactly\n this.headerClone.style.left = `${containerRect.left}px`;\n this.headerClone.style.width = `${containerRect.width}px`;\n }\n \n // Update horizontal scroll position\n this.updateCloneHorizontalPosition();\n }\n \n private updateCloneHorizontalPosition() {\n if (!this.headerClone) return;\n \n // Get current scroll position of table\n const scrollLeft = this.tableTarget.scrollLeft;\n \n // Apply transform to non-sticky cells\n const nonStickyCells = this.getNonStickyColumnCells(this.headerClone);\n nonStickyCells.forEach((cell: HTMLElement) => {\n cell.style.transform = `translateX(-${scrollLeft}px)`;\n });\n }\n\n setupActiveElementObserver() {\n // Create an intersection observer to detect when active elements are obscured by the header\n this.activeElementObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n // Only handle elements that are actually active when they become obscured\n if (!this.isHeaderSticky || entry.target !== document.activeElement) {\n return;\n }\n\n // If the element is intersecting less than 90% of its area, it's partially obscured\n const isSignificantlyObscured = entry.intersectionRatio < 0.9;\n\n // We also check using our helper method\n const isObscured = this.isElementObscuredByHeader(entry.target);\n\n if (isSignificantlyObscured || isObscured) {\n this.scrollActiveElementIntoView(entry.target);\n }\n });\n },\n {\n rootMargin: `-${this.headerHeight}px 0px 0px 0px`,\n threshold: [0, 0.1, 0.5, 0.9, 1.0] // Monitor several threshold levels for better accuracy\n }\n );\n }\n} ","// The BulkController can be used for adding bulk operations to your index views.\n// You can add a Select All checkbox and checkboxes for each record and easily grab\n// the selected records.\n//\n// Usage:\n//\n// import BulkController from \"controllers/bulk_controller\"\n//\n// export default class extends BulkController {\n// }\n\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"checkbox\", \"selectAll\"];\n\n declare selectAllTarget: HTMLInputElement;\n declare checkboxTargets: HTMLInputElement[];\n\n // Toggles all checkboxes based upon what is currently checked\n toggleSelectAll(_event) {\n return !this.allCheckboxesSelected ? this.selectAll() : this.unselectAll();\n }\n\n // Selects all checkboxes\n selectAll() {\n this.selectAllTarget.checked = true;\n this.selectAllTarget.indeterminate = false;\n this.unselected.forEach((target) => (target.checked = true));\n }\n\n // Unselects all checkboxes\n unselectAll() {\n this.selectAllTarget.checked = false;\n this.selectAllTarget.indeterminate = false;\n this.selected.forEach((target) => (target.checked = false));\n }\n\n // Keep track of SelectAll state based upon how many checkboxes are selected\n change(_event: Event) {\n if (this.noCheckboxesSelected) {\n this.selectAllTarget.checked = false;\n this.selectAllTarget.indeterminate = false;\n } else if (this.allCheckboxesSelected) {\n this.selectAllTarget.checked = true;\n this.selectAllTarget.indeterminate = false;\n } else {\n this.selectAllTarget.indeterminate = true;\n }\n }\n\n // Returns true if Select All checkbox is checked\n get selectedAll() {\n return this.selectAllTarget.checked;\n }\n\n // Returns all selected checkboxes\n get selected() {\n return this.checkboxTargets.filter((target) => target.checked);\n }\n\n // Returns all unselected checkboxes\n get unselected() {\n return this.checkboxTargets.filter((target) => !target.checked);\n }\n\n // Returns data-id attributes for all selected checkboxes\n get selectedIds() {\n return this.selected.map((target) => target.dataset.id);\n }\n\n // Returns true if all checkboxes are checked\n get allCheckboxesSelected() {\n return this.checkboxTargets.every((target) => target.checked);\n }\n\n // Returns true if no checkboxes are checked\n get noCheckboxesSelected() {\n return this.checkboxTargets.every((target) => !target.checked);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"bulk-update-ledger-entries\"\nexport default class extends Controller {\n declare accountCodeSelectTarget: HTMLSelectElement;\n declare tagIdsSelectTarget: HTMLSelectElement;\n\n declare bulkEditMode: boolean;\n\n static targets = [\n \"accountCodeSelect\",\n \"tagIdsSelect\"\n ];\n\n toggleAccountCodeSelect(event: Event) {\n const target = event.currentTarget as HTMLInputElement;\n this.dispatch(\"toggleAccountCodeSelect\", { detail: { checked: target.checked } })\n }\n\n toggleTagSelect(event: Event) {\n const target = event.currentTarget as HTMLInputElement;\n this.dispatch(\"toggleTagSelect\", { detail: { checked: target.checked } })\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\ntype AccountType = \"Revenue\" | \"Expense\" | string\n\nexport default class extends Controller {\n static targets = [\"grossOption\", \"sourceOption\", \"useOption\"]\n\n declare grossOptionTarget: HTMLInputElement;\n declare sourceOptionTarget: HTMLInputElement;\n declare useOptionTarget: HTMLInputElement;\n\n declare hasGrossOptionTarget: boolean;\n declare hasSourceOptionTarget: boolean;\n declare hasUseOptionTarget: boolean;\n\n connect(): void {\n const accountTypeSelect = document.getElementById('account_template_account_type') as HTMLSelectElement;\n if (accountTypeSelect) {\n this.setDefaultForAccountType(accountTypeSelect.value);\n }\n }\n\n handleAccountTypeChange(event: CustomEvent): void {\n const accountType = event.detail.type;\n this.setDefaultForAccountType(accountType);\n }\n\n private setDefaultForAccountType(accountType: AccountType): void {\n if (!this.hasGrossOptionTarget || !this.hasSourceOptionTarget || !this.hasUseOptionTarget) {\n return;\n }\n\n this.grossOptionTarget.checked = false;\n this.sourceOptionTarget.checked = false;\n this.useOptionTarget.checked = false;\n\n switch(accountType) {\n case 'Revenue':\n this.sourceOptionTarget.checked = true;\n break;\n case 'Expense':\n this.useOptionTarget.checked = true;\n break;\n default:\n this.grossOptionTarget.checked = true;\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"cell-nav\"\nexport default class extends Controller {\n static targets = [\"cell\"];\n declare cellTargets: HTMLElement[];\n\n static values = {\n colCount: Number,\n groupsCount: Number,\n };\n declare colCountValue: number;\n declare groupsCountValue: number;\n\n handleEscapeOrEnterKey(event) {\n event.preventDefault();\n\n const inputElement = event.currentTarget as HTMLInputElement;\n inputElement.blur();\n }\n\n handleTab(event) {\n event.preventDefault();\n\n const currentCell = event.target as HTMLElement;\n const currentColIndex = parseInt(currentCell.dataset.colIndex, 10);\n const currentRowIndex = parseInt(currentCell.dataset.rowIndex, 10);\n const currentGroupIndex = parseInt(currentCell.dataset.groupIndex, 10);\n const currentGroupRowsCount = parseInt(currentCell.dataset.groupRowsCount, 10);\n\n let nextColIndex = currentColIndex + 1;\n let nextRowIndex = currentRowIndex;\n let nextGroupIndex = currentGroupIndex;\n\n // If we exceed the number of columns, loop back to the first column\n if (nextColIndex > this.colCountValue) {\n nextColIndex = 1; // Reset to the first column\n nextRowIndex = currentRowIndex + 1; // go to next row\n\n if (nextRowIndex >= currentGroupRowsCount) {\n nextRowIndex = 0; // Reset to the first line\n nextColIndex = 1; // Reset to the first column\n nextGroupIndex = currentGroupIndex + 1; // go to next group\n\n if (nextGroupIndex >= this.groupsCountValue) {\n nextGroupIndex = 0; // Reset to the first group\n }\n\n const cellFromNextGroup = this.findCell(nextColIndex, 0, nextGroupIndex);\n const isCellVisible = cellFromNextGroup ? cellFromNextGroup.offsetParent !== null : false;\n\n if (!isCellVisible) {\n nextGroupIndex = currentGroupIndex;\n }\n }\n }\n\n this.selectCell(nextColIndex, nextRowIndex, nextGroupIndex);\n }\n\n handleShiftTab(event) {\n event.preventDefault();\n\n const currentCell = event.target as HTMLElement;\n const currentColIndex = parseInt(currentCell.dataset.colIndex, 10);\n const currentRowIndex = parseInt(currentCell.dataset.rowIndex, 10);\n const currentGroupIndex = parseInt(currentCell.dataset.groupIndex, 10);\n\n let nextColIndex = currentColIndex - 1;\n let nextRowIndex = currentRowIndex;\n let nextGroupIndex = currentGroupIndex;\n\n // If we exceed the number of columns, loop back to the first column\n if (nextColIndex < 1) {\n nextColIndex = this.colCountValue; // Reset to the last column\n nextRowIndex = currentRowIndex - 1; // go to previous row\n\n if (nextRowIndex < 0) {\n nextGroupIndex = currentGroupIndex - 1; // go to previous group\n if (nextGroupIndex < 0) {\n nextGroupIndex = this.groupsCountValue - 1; // Reset to the last group\n }\n\n const cellFromPrevGroup = this.findCell(nextColIndex, 0, nextGroupIndex);\n const prevGroupRowsCount = cellFromPrevGroup ? parseInt(cellFromPrevGroup.dataset.groupRowsCount, 10) : 1;\n\n nextRowIndex = prevGroupRowsCount - 1;\n\n const isCellVisible = cellFromPrevGroup ? cellFromPrevGroup.offsetParent !== null : false;\n\n if (!isCellVisible) {\n nextGroupIndex = currentGroupIndex;\n nextRowIndex = parseInt(currentCell.dataset.groupRowsCount, 10) - 1;\n }\n }\n }\n\n this.selectCell(nextColIndex, nextRowIndex, nextGroupIndex);\n }\n\n handleDown(event) {\n event.preventDefault();\n\n const currentCell = event.target as HTMLElement;\n const currentColIndex = parseInt(currentCell.dataset.colIndex, 10);\n const currentRowIndex = parseInt(currentCell.dataset.rowIndex, 10);\n const currentGroupIndex = parseInt(currentCell.dataset.groupIndex, 10);\n const currentGroupRowsCount = parseInt(currentCell.dataset.groupRowsCount, 10);\n\n const nextColIndex = currentColIndex;\n let nextRowIndex = currentRowIndex + 1;\n let nextGroupIndex = currentGroupIndex;\n\n // If we exceed the number of lines, loop back to the first line\n if (nextRowIndex >= currentGroupRowsCount) {\n nextRowIndex = 0; // Reset to the first line\n nextGroupIndex = currentGroupIndex + 1; // go to next group\n\n if (nextGroupIndex >= this.groupsCountValue) {\n nextGroupIndex = 0; // Reset to the first group\n }\n\n const cellFromNextGroup = this.findCell(nextColIndex, 0, nextGroupIndex);\n const isCellVisible = cellFromNextGroup ? cellFromNextGroup.offsetParent !== null : false;\n\n if (!isCellVisible) {\n nextGroupIndex = currentGroupIndex;\n }\n }\n\n this.selectCell(nextColIndex, nextRowIndex, nextGroupIndex);\n }\n\n handleUp(event) {\n event.preventDefault();\n\n const currentCell = event.target as HTMLElement;\n const currentColIndex = parseInt(currentCell.dataset.colIndex, 10);\n const currentRowIndex = parseInt(currentCell.dataset.rowIndex, 10);\n const currentGroupIndex = parseInt(currentCell.dataset.groupIndex, 10);\n\n const nextColIndex = currentColIndex;\n let nextRowIndex = currentRowIndex - 1;\n let nextGroupIndex = currentGroupIndex;\n\n // If we exceed the number of rows, loop back to the first row\n if (nextRowIndex < 0) {\n nextGroupIndex = currentGroupIndex - 1; // go to prev group\n if (nextGroupIndex < 0) {\n nextGroupIndex = this.groupsCountValue - 1;\n }\n\n // select a cell from the next group to get the total lines for that group\n const cellFromNextGroup = this.findCell(nextColIndex, 0, nextGroupIndex);\n const isCellVisible = cellFromNextGroup ? cellFromNextGroup.offsetParent !== null : false;\n\n if (isCellVisible) {\n const nextGroupRowsCount = cellFromNextGroup ? parseInt(cellFromNextGroup.dataset.groupRowsCount, 10) : 1;\n nextRowIndex = nextGroupRowsCount - 1;\n } else {\n nextGroupIndex = currentGroupIndex;\n nextRowIndex = parseInt(currentCell.dataset.groupRowsCount, 10) - 1;\n }\n }\n\n this.selectCell(nextColIndex, nextRowIndex, nextGroupIndex);\n }\n\n findCell(nextColIndex: number, nextRowIndex: number, nextGroupIndex: number): HTMLElement | undefined {\n return this.cellTargets.find(cell =>\n parseInt(cell.dataset.colIndex, 10) === nextColIndex &&\n parseInt(cell.dataset.rowIndex, 10) === nextRowIndex &&\n parseInt(cell.dataset.groupIndex, 10) === nextGroupIndex\n );\n }\n\n selectCell(nextColIndex: number, nextRowIndex: number, nextGroupIndex: number): HTMLElement | undefined {\n const nextCell = this.findCell(nextColIndex, nextRowIndex, nextGroupIndex);\n\n if (nextCell) {\n // If this is the commentary column (last column)\n if (nextColIndex === this.colCountValue) {\n (nextCell as HTMLInputElement).focus();\n } else {\n // For number cells, click the parent to open the edit form\n nextCell.parentElement.click();\n }\n }\n\n return nextCell;\n }\n} \n","import CheckboxSelectAll from \"stimulus-checkbox-select-all\";\nimport SelectAllTopCheckboxController from \"./select_all_top_checkbox_controller\";\n\n// Overriding some of the functionality of the StimulusCheckboxSelectAll library so we can include a select all checkbox at the top of the list\n// The logic for that Select All checkbox will be controlled by the SelectAllTopCheckboxController\nexport default class extends CheckboxSelectAll {\n static outlets = [\"select-all-top-checkbox\"]\n\n declare selectAllTopCheckboxOutlet: SelectAllTopCheckboxController;\n declare hasSelectAllTopCheckboxOutlet: boolean;\n declare checkboxTargets: HTMLInputElement[];\n\n connect(): void {\n this.updateParentCheckboxState(null);\n }\n\n get allCheckboxTargets(): HTMLInputElement[] {\n return this.findAllCheckboxes(this.element as HTMLElement);\n }\n\n findAllCheckboxes(element: HTMLElement): HTMLInputElement[] {\n const checkboxes: HTMLInputElement[] = Array.from(element.querySelectorAll('input[type=\"checkbox\"]'));\n element.querySelectorAll('[data-controller=\"checkbox-select-all\"]').forEach(childControllerElement => {\n checkboxes.push(...this.findAllCheckboxes(childControllerElement as HTMLInputElement));\n });\n return checkboxes;\n }\n\n triggerInputEvent(checkbox: HTMLInputElement): void {\n const event = new Event('input', { bubbles: false, cancelable: true })\n\n checkbox.dispatchEvent(event);\n }\n\n toggle(e: Event): void {\n e.preventDefault()\n\n this.allCheckboxTargets.forEach(checkbox => {\n // @ts-ignore\n checkbox.checked = e.target.checked\n this.triggerInputEvent(checkbox)\n })\n if (this.hasSelectAllTopCheckboxOutlet) {\n // @ts-ignore\n this.selectAllTopCheckboxOutlet.refresh()\n }\n\n this.updateParentCheckboxState(null);\n\n // @ts-ignore\n this.dispatch(\"checked\")\n }\n\n updateParentCheckboxState(checkbox: HTMLInputElement): void {\n const parentCheckbox = this.element.querySelector('input[type=\"checkbox\"]') as HTMLInputElement;\n\n if (parentCheckbox) {\n const allCheckboxes = this.allCheckboxTargets.filter(checkbox => checkbox !== parentCheckbox);\n\n const allChecked = allCheckboxes.every(checkbox => checkbox.checked);\n const someChecked = allCheckboxes.some(checkbox => checkbox.checked);\n\n if (parentCheckbox !== checkbox) {\n parentCheckbox.checked = allChecked;\n parentCheckbox.indeterminate = !allChecked && someChecked;\n }\n }\n\n const parentControllerElement = (this.element.parentNode as HTMLElement).closest('[data-controller=\"checkbox-select-all toggle\"]');\n if (parentControllerElement && parentControllerElement !== this.element) {\n const parentController = this.application.getControllerForElementAndIdentifier(parentControllerElement, 'checkbox-select-all');\n if (parentController && typeof (parentController as this).updateParentCheckboxState === 'function') {\n (parentController as this).updateParentCheckboxState(null);\n }\n }\n }\n\n checkboxUpdated(event: CustomEvent): void {\n this.updateParentCheckboxState(event.detail.checkbox);\n event.stopPropagation();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nexport default class extends Controller {\n static targets = [\"checkboxGroup\", \"checkbox\"];\n static values = { selectedGroup: Number }\n\n declare checkboxTargets: HTMLInputElement[];\n declare checkboxGroupTargets: HTMLInputElement[];\n declare selectedGroupValue: number;\n\n toggle(e: Event): void {\n const currentTarget = e.currentTarget as HTMLInputElement;\n let groupId\n this.checkboxGroupTargets.forEach((checkboxGroup) => {\n if (checkboxGroup.contains(currentTarget)) {\n groupId = checkboxGroup.dataset.groupId;\n }\n });\n this.checkboxTargets.forEach((checkbox) => {\n if (checkbox.dataset.groupId !== groupId) {\n checkbox.checked = false;\n checkbox.indeterminate = false;\n }\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"select-toggle\"\nexport default class extends Controller {\n static targets = [\"field\"];\n\n declare fieldTarget: HTMLInputElement;\n\n click(event: Event): void {\n event.preventDefault();\n this.fieldTarget.click();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport ClipboardJS from \"clipboard\";\nimport tippy from \"tippy.js\";\n\nexport default class extends Controller {\n static values = {\n successMessage: String,\n errorMessage: String,\n };\n\n declare clipboard: ClipboardJS;\n declare successMessageValue: string | undefined;\n declare errorMessageValue: string | undefined;\n\n connect() {\n this.clipboard = new ClipboardJS(this.element);\n this.clipboard.on(\"success\", (_e) => this.tooltip(this.successMessage));\n this.clipboard.on(\"error\", (_e) => this.tooltip(this.errorMessage));\n }\n\n tooltip(message) {\n tippy(this.element, {\n content: message,\n showOnCreate: true,\n onHidden: (instance) => {\n instance.destroy();\n },\n });\n }\n\n get successMessage() {\n return this.successMessageValue || \"Copied!\";\n }\n\n get errorMessage() {\n return this.errorMessageValue || \"Failed!\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"compare-to-last-period-button\"\nexport default class extends Controller {\n declare ledgersTarget: HTMLSelectElement;\n declare buttonTarget: HTMLInputElement;\n declare infoTarget: HTMLDivElement;\n declare textTarget: HTMLSpanElement;\n declare colTagTargets: HTMLInputElement[];\n\n declare hasIntervalSelectTarget: boolean;\n declare intervalSelectTarget: HTMLSelectElement;\n \n declare hasConsolidatedBreakdownTarget: boolean;\n declare consolidatedBreakdownTarget: HTMLInputElement;\n\n declare hasMergeEntitiesToggleTarget: boolean;\n declare mergeEntitiesToggleTarget: HTMLInputElement;\n\n static targets = [\n \"ledgers\",\n \"button\",\n \"info\",\n \"text\",\n \"intervalSelect\",\n \"consolidatedBreakdown\",\n \"colTag\",\n \"mergeEntitiesToggle\"\n ];\n\n canCompare() {\n const hasOneLedger =\n Array.from(this.ledgersTarget.children).filter((ledger: HTMLOptionElement) => ledger.selected).length == 1;\n\n const isNotInterval = this.hasIntervalSelectTarget && this.intervalSelectTarget.value === \"none\";\n const hasNoColTags = Array.from(this.colTagTargets).every(checkbox => checkbox.checked === false);\n const mergeEntities = this.hasMergeEntitiesToggleTarget && this.mergeEntitiesToggleTarget.checked === true;\n\n if (this.hasConsolidatedBreakdownTarget) {\n const isOnlyConsolidated = !this.consolidatedBreakdownTarget.checked;\n\n return hasOneLedger && isOnlyConsolidated && isNotInterval && hasNoColTags;\n } else {\n return (hasOneLedger && isNotInterval && hasNoColTags) || (isNotInterval && hasNoColTags && mergeEntities);\n }\n }\n\n setButton() {\n if (this.canCompare()) {\n this.buttonTarget.disabled = false;\n this.infoTarget.classList.add(\"hidden\");\n this.textTarget.classList.remove(\"text-gray-400\");\n } else {\n this.buttonTarget.disabled = true;\n this.buttonTarget.checked = false;\n this.infoTarget.classList.remove(\"hidden\");\n this.textTarget.classList.add(\"text-gray-400\");\n }\n }\n\n connect() {\n this.setButton();\n }\n}\n\n\n","import { Controller } from \"@hotwired/stimulus\";\n\ninterface newRuleConditions {\n ledgerId: string | null;\n accountTemplateId: string | null;\n description: string | null;\n amount: string | null;\n}\n\n// Connects to data-controller=\"connected-transaction\"\nexport default class extends Controller {\n declare actionsDropdownTarget: HTMLElement;\n declare hasActionsDropdownTarget: boolean;\n declare categorizationActionButtonTargets: HTMLElement[];\n declare checkboxTarget: HTMLInputElement;\n declare hasCheckboxTarget: boolean;\n declare submitTarget: HTMLButtonElement;\n declare transferTarget: HTMLButtonElement;\n declare hasTransferTarget: boolean;\n declare transactionRowTarget: HTMLDivElement;\n declare accountSelectTarget: HTMLSelectElement;\n declare hasAccountSelectTarget: HTMLSelectElement;\n declare newRuleLinkTriggerTargets: HTMLInputElement[];\n declare hasNewRuleLinkTarget: boolean;\n declare newRuleLinkTarget: HTMLButtonElement;\n declare accountCodeSelectTarget: HTMLSelectElement;\n declare hasAccountCodeSelectTarget: HTMLSelectElement;\n declare tagSelectTarget: HTMLSelectElement;\n declare hasTagSelectTarget: HTMLSelectElement;\n declare hasSuggestionIconTarget: boolean;\n declare suggestionIconTarget: HTMLDivElement;\n declare splitTransactionButtonTarget: HTMLButtonElement;\n declare hasSplitTransactionButtonTarget: boolean;\n\n declare submitClassesToRemoveValue: string;\n declare submitClassesToAddValue: string;\n declare transferClassesToRemoveValue: string;\n declare transferClassesToAddValue: string;\n declare newRuleConditionsValue: newRuleConditions;\n declare newRuleUrlValue: string;\n\n declare hasPotentialTransferClasses: Array;\n\n static targets = [\n \"actionsDropdown\",\n \"categorizationActionButton\",\n \"checkbox\",\n \"submit\",\n \"transactionRow\",\n \"accountSelect\",\n \"newRuleLinkTrigger\",\n \"accountCodeSelect\",\n \"tagSelect\",\n \"splitTransactionButton\",\n \"newRuleLink\",\n \"suggestionIcon\",\n ];\n\n static values = {\n newRuleConditions: {\n type: Object,\n default: {\n ledgerId: null,\n accountTemplateId: null,\n description: null,\n amount: null,\n },\n },\n newRuleUrl: String,\n submitClassesToAdd: String,\n submitClassesToRemove: String,\n };\n\n connect() {\n this.changeReviewedStatus();\n this.toggleNewRuleLink();\n this.updateSplitTransactionButton();\n }\n\n changeReviewedStatus() {\n if (this.hasAccountSelectTarget && (!this.hasCheckboxTarget || !this.checkboxTarget.checked)) {\n const accountSelected = this.accountSelectTarget.value;\n\n if (accountSelected === \"\" || accountSelected === undefined) {\n this.markUnreviewed();\n } else {\n this.markReviewed();\n }\n }\n }\n\n markReviewed() {\n this.submitTarget.disabled = false;\n this.submitTarget.classList.remove(...this.submitClassesToRemoveValue.split(\" \"));\n this.submitTarget.classList.add(...this.submitClassesToAddValue.split(\" \"));\n }\n\n markUnreviewed() {\n this.submitTarget.disabled = true;\n this.submitTarget.classList.add(...this.submitClassesToRemoveValue.split(\" \"));\n this.submitTarget.classList.remove(...this.submitClassesToAddValue.split(\" \"));\n }\n\n toggleActions() {\n if (this.hasCheckboxTarget && this.checkboxTarget.checked) {\n this.categorizationActionButtonTargets.forEach((button) => {\n button.setAttribute(\"disabled\", \"\");\n });\n \n if (this.hasActionsDropdownTarget) {\n this.actionsDropdownTarget.removeAttribute(\"data-controller\")\n this.actionsDropdownTarget.classList.remove(\"cursor-pointer\", \"hover:bg-zinc-200\");\n this.actionsDropdownTarget.classList.add(\"cursor-not-allowed\");\n this.actionsDropdownTarget.setAttribute(\"disabled\", \"\");\n }\n\n this.markUnreviewed(); \n } else if (this.hasCheckboxTarget && !this.checkboxTarget.checked) {\n this.categorizationActionButtonTargets.forEach((button) => {\n button.removeAttribute(\"disabled\");\n });\n\n if (this.hasActionsDropdownTarget) {\n this.actionsDropdownTarget.setAttribute(\"data-controller\", \"dropdown\")\n this.actionsDropdownTarget.classList.add(\"cursor-pointer\", \"hover:bg-zinc-200\");\n this.actionsDropdownTarget.classList.remove(\"cursor-not-allowed\");\n this.actionsDropdownTarget.removeAttribute(\"disabled\");\n }\n\n this.changeReviewedStatus();\n }\n }\n\n toggleNewRuleLink() {\n if (this.hasNewRuleLinkTarget) {\n if (this.newRuleLinkTriggerTargets.some((target) => !!target.value)) {\n this.newRuleLinkTarget.classList.remove(\"hidden\");\n } else {\n this.newRuleLinkTarget.classList.add(\"hidden\");\n }\n }\n }\n\n handleUpdates(_event) {\n this.toggleNewRuleLink();\n this.removeSuggestionIcon();\n this.updateSplitTransactionButton();\n }\n\n updateSplitTransactionButton() {\n const queryParams = new URLSearchParams();\n\n if (this.hasAccountSelectTarget && this.accountSelectTarget.value) {\n queryParams.append(\"destination_account_id\", this.accountSelectTarget.value);\n }\n\n if (this.hasAccountCodeSelectTarget && this.accountCodeSelectTarget.value) {\n queryParams.append(\"account_code_id\", this.accountCodeSelectTarget.value);\n }\n\n if (this.hasTagSelectTarget && this.tagSelectTarget.value) {\n Array.from(this.tagSelectTarget.selectedOptions).forEach((option) => {\n queryParams.append(\"tag_ids[]\", option.value);\n });\n }\n\n if (this.hasSplitTransactionButtonTarget) {\n const card = JSON.parse(this.splitTransactionButtonTarget.dataset.card);\n\n const urlOrigin = card.turboSrc.split(\"?\")[0];\n\n card.turboSrc = urlOrigin + \"?\" + queryParams.toString();\n\n this.splitTransactionButtonTarget.dataset.card = JSON.stringify(card);\n }\n }\n\n removeSuggestionIcon() {\n if (this.hasSuggestionIconTarget) {\n this.suggestionIconTarget.classList.add(\"hidden\");\n }\n }\n\n visitNewRuleLink() {\n const url = new URL(this.newRuleUrlValue);\n const queryParams = new URLSearchParams({\n \"ledger_ids[]\": this.newRuleConditionsValue.ledgerId,\n \"account_template_ids[]\": this.newRuleConditionsValue.accountTemplateId,\n q: this.newRuleConditionsValue.description,\n amount: this.newRuleConditionsValue.amount,\n });\n\n if (this.accountSelectTarget.value) {\n queryParams.append(\"destination_account_id\", this.accountSelectTarget.value);\n }\n\n if (this.accountCodeSelectTarget.value) {\n queryParams.append(\"account_code_id\", this.accountCodeSelectTarget.value);\n }\n\n Array.from(this.tagSelectTarget.selectedOptions).forEach((option) => {\n queryParams.append(\"tag_ids[]\", option.value);\n });\n\n url.search = queryParams.toString();\n\n window.open(url, \"_blank\").focus();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"connected-transactions\"\nexport default class extends Controller {\n declare transactionRowTargets: HTMLDivElement[];\n declare loaderTarget: HTMLDivElement;\n declare urlValue: string;\n\n static targets = [\n \"accountSelect\",\n \"transactionRow\",\n \"loader\",\n \"bulkApproveButton\",\n \"bulkIgnoreButton\",\n \"bulkUpdateButton\",\n \"bankTransactionCount\",\n \"bulkEditErrors\",\n \"checkbox\",\n \"ignoreTransactionButton\",\n ];\n static values = { url: String };\n\n declare accountSelectTargets: HTMLSelectElement[];\n declare bulkApproveButtonTarget: HTMLButtonElement;\n declare bulkIgnoreButtonTarget: HTMLButtonElement;\n declare bulkUpdateButtonTarget: HTMLButtonElement;\n declare bulkEditErrorsTarget: HTMLDivElement;\n declare bankTransactionCountTargets: HTMLSpanElement[];\n declare checkboxTargets: HTMLInputElement[];\n declare ignoreTransactionButtonTargets: HTMLButtonElement[];\n\n loadNewTransactionsIfNeeded() {\n const numRows = this.transactionRowTargets.length;\n\n if (numRows === 1) {\n this.loaderTarget.classList.remove('hidden');\n this.setLastRecordFormParam(this.transactionRowTargets[0]);\n }\n }\n\n createBulkApproveInput(form: HTMLFormElement, name: string, value: string) {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `connected_transactions[]${name}`;\n input.value = value;\n form.appendChild(input);\n }\n\n bulkApprove(event) {\n event.preventDefault();\n const target = event.currentTarget as HTMLButtonElement;\n const form = target.form;\n const selectedRows = this.getSelectedCheckboxes();\n const selectedDestinationAccounts = this.getSelectedDestinationAccounts();\n \n this.disableBulkActionButtons();\n\n selectedRows.forEach(checkbox => {\n const accountSelect = selectedDestinationAccounts.find((select) => {\n return select.dataset.connectedTransactionsBankTransactionIdValue === checkbox.value\n });\n\n if (accountSelect.value !== \"\") {\n const formData = new FormData(accountSelect.form);\n const connectedTransactionId = checkbox.value;\n\n this.createBulkApproveInput(form, '[id]', connectedTransactionId);\n this.createBulkApproveInput(form, '[account_id]', formData.get(\"destination_account_id\") as string);\n this.createBulkApproveInput(form, '[account_code_id]', formData.get(\"account_code_id\") as string);\n formData.getAll(\"transaction_tag_ids[]\").forEach((transactionTagId) => {\n this.createBulkApproveInput(form, '[tag_ids][]', transactionTagId as string);\n });\n }\n });\n\n form.requestSubmit();\n }\n\n bulkIgnore(event) {\n event.preventDefault();\n const target = event.currentTarget as HTMLButtonElement;\n const form = target.form;\n const selectedRows = this.getSelectedCheckboxes();\n\n this.disableBulkActionButtons();\n\n selectedRows.forEach((checkbox) => {\n const input = document.createElement(\"input\");\n input.name = \"bank_transaction_ids[]\";\n input.type = \"hidden\";\n input.value = checkbox.value;\n form.appendChild(input);\n });\n\n form.requestSubmit();\n }\n\n disableBulkActionButtons() {\n this.bulkApproveButtonTarget.setAttribute(\"disabled\", \"\");\n this.bulkIgnoreButtonTarget.setAttribute(\"disabled\", \"\");\n this.bulkUpdateButtonTarget.setAttribute(\"disabled\", \"\");\n }\n\n updateBulkActionButtons() {\n const selectedRows = this.getSelectedCheckboxes();\n const count = selectedRows.length;\n\n const selectedDestinationAccounts = this.getSelectedDestinationAccounts();\n const selectedDestinationAccountBankTransactionIds = selectedDestinationAccounts.map((select) => {\n return select.dataset.connectedTransactionsBankTransactionIdValue;\n });\n const selectedRowBankTransactionIds = selectedRows.map(checkbox => checkbox.value);\n const allSelectedRowsHaveDestinationAccounts = selectedRowBankTransactionIds.every((id) => {\n return selectedDestinationAccountBankTransactionIds.includes(id)\n });\n\n this.bulkEditErrorsTarget.classList.add(\"hidden\");\n this.bulkUpdateButtonTarget.disabled = count === 0;\n this.bulkIgnoreButtonTarget.disabled = count === 0;\n \n if (count !== 0 && allSelectedRowsHaveDestinationAccounts) {\n this.bulkApproveButtonTarget.removeAttribute(\"disabled\");\n } else {\n this.bulkApproveButtonTarget.setAttribute(\"disabled\", \"\");\n }\n\n this.bankTransactionCountTargets.forEach((el) => {\n el.innerText = count.toString();\n el.classList.toggle(\"hidden\", count === 0);\n });\n }\n\n getSelectedCheckboxes() {\n return this.checkboxTargets.filter((checkbox) => {\n return checkbox.checked;\n });\n }\n\n getSelectedDestinationAccounts() {\n return this.accountSelectTargets.filter(select => select.value !== \"\");\n }\n\n setLastRecordFormParam(row) {\n const transactionForm = row.querySelector(\"form\");\n const formActionUrl = new URL(transactionForm.action);\n const searchParams = new URLSearchParams(formActionUrl.search);\n searchParams.set('last_record', 'true');\n formActionUrl.search = searchParams.toString();\n transactionForm.action = formActionUrl.toString();\n }\n}\n","import * as math from \"mathjs\";\n\ninterface CurrencyFormatterOptions {\n throwOnInvalid?: boolean;\n}\n\nexport function formatCurrencyValue(inputValue: string, options: CurrencyFormatterOptions = {}): string {\n // Remove all non-numerical characters except for math operators (+, -, *, /) and decimal point\n const patterns = {\n commas: \",\",\n leadingZeros: \"^0+(?=\\\\d)\", // zeros at start only if followed by digit\n nonMathChars: \"[^0-9.+-/*]\", // anything that's not a number or math operator\n };\n\n const cleanupPattern = new RegExp(`${patterns.commas}|${patterns.leadingZeros}|${patterns.nonMathChars}`, \"g\");\n const numericValue = inputValue.replace(cleanupPattern, \"\");\n\n let result = \"\";\n try {\n result = math.evaluate(numericValue);\n } catch {\n if (options.throwOnInvalid) {\n throw new Error(\"Invalid numeric expression. Could not parse: \" + inputValue + \" as \" + numericValue);\n }\n }\n\n let numberValue = parseFloat(result);\n if (isNaN(numberValue) || numberValue === Infinity) {\n if (options.throwOnInvalid) {\n throw new Error(\"Invalid number. Could not parse: \" + inputValue + \" as \" + result);\n }\n numberValue = 0;\n }\n\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n }).format(numberValue);\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { formatCurrencyValue } from \"../helpers/currency_formatter\"\n\n// Connects to data-controller=\"copy-amount\"\nexport default class extends Controller {\n static targets = [\"sourceAmountField\", \"targetAmountField\"]\n\n declare sourceAmountFieldTarget: HTMLInputElement;\n declare targetAmountFieldTarget: HTMLInputElement;\n declare hasSourceAmountFieldTarget: boolean;\n declare hasTargetAmountFieldTarget: boolean;\n\n connect() {\n this.updateAmount();\n }\n\n updateAmount() {\n if (this.hasSourceAmountFieldTarget && this.hasTargetAmountFieldTarget) {\n try {\n const formattedValue = formatCurrencyValue(this.sourceAmountFieldTarget.value, { throwOnInvalid: true });\n this.targetAmountFieldTarget.value = formattedValue;\n } catch {\n this.targetAmountFieldTarget.value = \"\";\n }\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus';\n\n// Connects to data-controller=\"counter\"\nexport default class extends Controller {\n declare countToDecrementValue: number;\n declare countToIncrementValue: number;\n declare decrementTarget: HTMLElement;\n declare incrementTarget: HTMLElement;\n\n static targets = ['decrement', 'increment'];\n static values = {\n countToDecrement: {\n type: Number,\n default: 0\n },\n countToIncrement: {\n type: Number,\n default: 0\n }\n }\n\n countToDecrementValueChanged(value) {\n this.decrementTarget.textContent = value.toLocaleString();\n }\n\n countToIncrementValueChanged(value) {\n this.incrementTarget.textContent = value.toLocaleString();\n }\n\n decrement() {\n this.countToDecrementValue = Math.max(this.countToDecrementValue - 1, 0);\n }\n\n increment() {\n this.countToIncrementValue += 1;\n }\n}\n","import { Controller } from '@hotwired/stimulus';\n\n// Connects to data-controller=\"currency-subtotal\"\nexport default class extends Controller {\n declare differenceTarget: HTMLElement;\n declare selectedAmountValue: number;\n declare hasLineItemTarget: boolean;\n declare lineItemTargets: HTMLInputElement[];\n declare submitButtonTarget: HTMLButtonElement;\n declare totalTarget: HTMLElement;\n declare totalValue: number;\n\n static targets = [\n \"difference\",\n \"lineItem\",\n \"submitButton\",\n \"total\"\n ];\n\n static values = {\n selectedAmount: {\n type: Number,\n default: 0\n },\n total: {\n type: Number,\n default: 0\n },\n }\n\n totalValueChanged() {\n this.updateTotalText();\n this.updateDifferenceText();\n this.toggleSubmitButton();\n }\n\n differenceValue() {\n return Math.abs(this.selectedAmountValue) - this.totalValue;\n }\n\n toggleSubmitButton() {\n if (this.differenceValue() == 0) {\n this.submitButtonTarget.removeAttribute(\"disabled\");\n } else {\n this.submitButtonTarget.setAttribute(\"disabled\", \"disabled\");\n }\n }\n\n updateDifferenceText() {\n if (this.differenceValue() == 0) {\n this.differenceTarget.textContent = \"\";\n } else if (this.differenceValue() > 0) {\n this.differenceTarget.textContent = `Missing: ${this.differenceValue().toLocaleString('en-US', { style: 'currency', currency: 'USD' })}`;\n } else {\n this.differenceTarget.textContent = `Excess: ${Math.abs(this.differenceValue()).toLocaleString('en-US', { style: 'currency', currency: 'USD' })}`;\n }\n }\n\n updateTotal() {\n if (this.hasLineItemTarget) {\n this.totalValue = this.lineItemTargets.reduce((total, element) => {\n return element.checked \n ? total + parseFloat(element.dataset.currencySubtotalLineItemAmountValue) \n : total;\n }, 0);\n }\n }\n\n updateTotalText() {\n this.totalTarget.textContent = this.totalValue.toLocaleString('en-US', { style: 'currency', currency: 'USD' });\n }\n}\n","export function parseDateRangeOption(value): { startDate: Date | null, endDate: Date | null, comparable: string } {\n const today = new Date();\n let startDate: Date, endDate: Date;\n let comparable = 'false';\n\n switch (value) {\n case \"All\":\n startDate = null;\n endDate = null;\n break;\n case \"since_inception\":\n startDate = null;\n endDate = today;\n break;\n case \"this_month\":\n startDate = new Date(today.getFullYear(), today.getMonth(), 1);\n endDate = new Date(today.getFullYear(), today.getMonth() + 1, 0);\n comparable = 'month';\n break;\n case \"this_month_to_date\":\n startDate = new Date(today.getFullYear(), today.getMonth(), 1);\n endDate = today;\n break;\n case \"this_quarter\":\n startDate = new Date(today.getFullYear(), getQuarterStartMonth(today), 1);\n endDate = new Date(today.getFullYear(), getQuarterStartMonth(today) + 3, 0);\n comparable = 'quarter';\n break;\n case \"this_quarter_to_date\":\n startDate = new Date(today.getFullYear(), getQuarterStartMonth(today), 1);\n endDate = today;\n break;\n case \"this_year\":\n startDate = new Date(today.getFullYear(), 0, 1);\n endDate = new Date(today.getFullYear(), 11, 31);\n comparable = 'year';\n break;\n case \"this_year_to_date\":\n startDate = new Date(today.getFullYear(), 0, 1);\n endDate = today;\n break;\n case \"this_half_year\":\n if (today.getMonth() < 6) {\n // First half of the year: Jan 1 - Jun 30\n startDate = new Date(today.getFullYear(), 0, 1);\n endDate = new Date(today.getFullYear(), 5, 30);\n } else {\n // Second half of the year: Jul 1 - Dec 31\n startDate = new Date(today.getFullYear(), 6, 1);\n endDate = new Date(today.getFullYear(), 11, 31);\n }\n comparable = 'half_year';\n break;\n case \"last_month\":\n startDate = new Date(today.getFullYear(), today.getMonth() - 1, 1);\n endDate = new Date(today.getFullYear(), today.getMonth(), 0);\n comparable = 'month';\n break;\n case \"last_quarter\":\n startDate = new Date(today.getFullYear(), getQuarterStartMonth(today) - 3, 1);\n endDate = new Date(today.getFullYear(), getQuarterStartMonth(today), 0);\n comparable = 'quarter';\n break;\n case \"last_year\":\n startDate = new Date(today.getFullYear() - 1, 0, 1);\n endDate = new Date(today.getFullYear() - 1, 11, 31);\n comparable = 'year';\n break;\n case \"last_half_year\":\n if (today.getMonth() < 6) {\n // Last half of the previous year: Jul 1 - Dec 31\n startDate = new Date(today.getFullYear() - 1, 6, 1);\n endDate = new Date(today.getFullYear() - 1, 11, 31);\n } else {\n // First half of this year: Jan 1 - Jun 30\n startDate = new Date(today.getFullYear(), 0, 1);\n endDate = new Date(today.getFullYear(), 5, 30);\n }\n comparable = 'half_year';\n break;\n default:\n startDate = new Date(value);\n endDate = today;\n }\n\n return { startDate, endDate, comparable };\n}\n\nexport function getQuarterStartMonth(today: Date): number {\n return Math.floor(today.getMonth() / 3) * 3;\n}\n","import StimulusFlatpickr from \"stimulus-flatpickr\";\nimport { Instance } from \"flatpickr/dist/types/instance\";\nimport { Options } from \"flatpickr/dist/types/options\";\nimport { parseDateRangeOption } from \"../helpers/date_range_option_parser\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\ntype DispatchOptions = Partial<{\n target: Element | Window | Document;\n detail: object;\n prefix: string;\n bubbles: boolean;\n cancelable: boolean;\n}>;\n\nexport default class extends StimulusFlatpickr {\n declare config: Options;\n declare dispatch: (eventName: string, options?: DispatchOptions) => CustomEvent;\n declare fp: Instance;\n declare startDateTarget: HTMLInputElement;\n declare endDateTarget: HTMLInputElement;\n declare dateRangeTarget: TomInput;\n declare intervalTarget: HTMLSelectElement;\n declare compareableTarget: HTMLInputElement;\n\n static targets = [\"startDate\", \"endDate\", \"dateRange\", \"interval\", \"compareable\"];\n\n initialize() {\n this.config = {\n mode: \"range\",\n showMonths: 2,\n clickOpens: false,\n dateFormat: \"m/d/Y\",\n };\n }\n\n toDate(string) {\n return string.split(\"T\")[0];\n }\n\n // Hook fired when calendar is closed\n close(selectedDates, dateStr, _instance) {\n if (selectedDates.length === 2) {\n this.startDateTarget.value = this.toDate(selectedDates[0].toISOString());\n this.endDateTarget.value = this.toDate(selectedDates[1].toISOString());\n this.dateRangeTarget.tomselect.updateOption(\"SelectedDateRange\", {\n value: \"SelectedDateRange\",\n text: dateStr,\n optgroup: 1,\n disabled: false,\n hidden: true,\n });\n this.dateRangeTarget.tomselect.setValue(\"SelectedDateRange\");\n this.dateRangeTarget.tomselect.refreshOptions(false);\n\n const formElement = document.getElementById(\"filters-form\");\n\n if (formElement) {\n const event = new Event(\"submit\", { bubbles: true });\n // Submitting the event from the filters-form element\n formElement.dispatchEvent(event);\n } else {\n this.dispatch(\"submit\");\n }\n } else if (this.dateRangeTarget.tomselect.getValue() === \"NewDateRange\") {\n this.clearStartAndEndDates();\n }\n }\n\n // Action invoked when tomselect option is selected\n input({ target: { value } }) {\n if (!value) {\n return;\n } else if (value === \"SelectedDateRange\") {\n return;\n } else if (value === \"NewDateRange\") {\n this.fp.clear();\n\n const currentMonth = new Date().getMonth();\n this.fp.changeMonth(currentMonth - 1, false); // Display the 2-month calendar spread starting with the month prior to the current month\n const currentYear = new Date().getFullYear();\n this.fp.changeYear(currentYear);\n\n this.fp.open();\n } else {\n const { startDate, endDate, comparable } = parseDateRangeOption(value);\n\n this.startDateTarget.value = startDate == null ? \"\" : this.toDate(startDate.toISOString());\n this.endDateTarget.value = endDate == null ? \"\" : this.toDate(endDate.toISOString());\n this.compareableTarget.value = comparable;\n\n this.dispatch(\"submit\");\n }\n }\n\n clearStartAndEndDates() {\n this.dateRangeTarget.tomselect.updateOption(\"SelectedDateRange\", {\n value: \"SelectedDateRange\",\n text: \"No Selected Range\",\n optgroup: 1,\n disabled: true,\n });\n this.dateRangeTarget.tomselect.clear();\n this.dateRangeTarget.tomselect.refreshOptions(false);\n\n this.startDateTarget.value = null;\n this.endDateTarget.value = null;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport Sortable from \"sortablejs\";\nimport { patch } from \"@rails/request.js\";\nimport { Turbo } from \"@hotwired/turbo-rails\";\n\n// Connects to data-controller=\"drag\"\nexport default class extends Controller {\n declare handleValue: string;\n declare positionTargets: HTMLElement[];\n declare sortable: Sortable;\n\n declare objectNameValue: string;\n declare objectAttributeValue: string;\n\n declare disabledValue: boolean;\n\n static targets = [\"position\"];\n\n static values = {\n handle: String,\n objectName: String,\n objectAttribute: String,\n disabled: {\n type: Boolean,\n default: false,\n },\n };\n\n connect() {\n this.sortable = Sortable.create(this.element, {\n handle: this.handleValue,\n group: \"shared\",\n disabled: this.disabledValue,\n animation: 150,\n onEnd: this.end.bind(this),\n });\n }\n\n async end(event) {\n const url = event.item.getAttribute(\"data-drag-url\");\n const data = this.buildPayload(event);\n\n if (event.newIndex === event.oldIndex) return;\n\n const response = await patch(url, {\n body: data,\n contentType: \"application/json\",\n responseKind: \"json\",\n });\n\n if (response.ok) {\n this.positionTargets.forEach((el, index) => (el.textContent = (index + 1).toString()));\n } else {\n Turbo.visit(window.location.href, { action: \"replace\" });\n }\n }\n\n buildPayload(event) {\n const data = {};\n data[this.objectNameValue] = {};\n data[this.objectNameValue][this.objectAttributeValue] = event.newIndex + 1;\n\n return data;\n }\n\n disconnect() {\n this.sortable.destroy();\n }\n}\n","import { Dropdown } from \"tailwindcss-stimulus-components\"\n\nexport default class extends Dropdown {\n static targets = [\"menu\"];\n declare menuTarget: HTMLElement;\n declare element: HTMLElement;\n private observer: MutationObserver;\n\n connect(): void {\n super.connect();\n\n this.observer = new MutationObserver(() => {\n const isOpen = this.element.dataset.dropdownWithTooltipOpenValue === 'true';\n const controllers = this.element.dataset.controller?.split(\" \") || [];\n\n this.element.dataset.controller = isOpen\n ? controllers.filter(c => c !== \"stimulus-tooltip\").join(\" \")\n : [...new Set([...controllers, \"stimulus-tooltip\"])].join(\" \")\n });\n\n this.observer.observe(this.element, {\n attributes: true,\n attributeFilter: ['data-dropdown-with-tooltip-open-value']\n });\n }\n\n disconnect(): void {\n super.disconnect();\n this.observer.disconnect();\n }\n}\n","import Dropzone from \"dropzone\";\nimport { DropzoneFile } from \"dropzone\";\nimport { Controller } from \"@hotwired/stimulus\";\nimport { DirectUpload } from \"@rails/activestorage\";\nimport { getMetaValue, findElement, removeElement, insertAfter } from \"../helpers\";\n\ninterface CustomDropzoneFile extends DropzoneFile {\n controller: DirectUploadController;\n}\n\n// Pulled from https://web-crunch.com/posts/rails-drag-drop-active-storage-stimulus-dropzone\n\n// Connects to data-controller=\"dropzone\"\nexport default class DropZoneController extends Controller {\n static targets = [\"input\"];\n\n declare dropZone: Dropzone | undefined;\n declare inputTarget: HTMLInputElement;\n\n connect() {\n if (!this.dropZone) {\n this.dropZone = createDropZone(this);\n }\n this.hideFileInput();\n this.bindEvents();\n\n const dz = Dropzone;\n dz.autoDiscover = false; // necessary quirk for Dropzone error in console\n }\n\n // Private\n hideFileInput() {\n this.inputTarget.disabled = true;\n this.inputTarget.style.display = \"none\";\n }\n\n bindEvents() {\n this.dropZone.on(\"addedfile\", (file: CustomDropzoneFile) => {\n setTimeout(() => {\n return file.accepted && createDirectUploadController(this, file).start();\n }, 500);\n });\n\n this.dropZone.on(\"removedfile\", (file: CustomDropzoneFile) => {\n return file.controller && removeElement(file.controller.hiddenInput);\n });\n\n this.dropZone.on(\"canceled\", (file: CustomDropzoneFile) => {\n return file.controller && file.controller.xhr.abort();\n });\n }\n\n get headers() {\n return { \"X-CSRF-Token\": getMetaValue(\"csrf-token\") };\n }\n\n get url() {\n return this.inputTarget.getAttribute(\"data-direct-upload-url\") || undefined;\n }\n\n get maxFiles() {\n return Number(this.data.get(\"maxFiles\")) || 1;\n }\n\n get maxFileSize() {\n return Number(this.data.get(\"maxFileSize\")) || 256;\n }\n\n get acceptedFiles() {\n return this.data.get(\"acceptedFiles\") || undefined;\n }\n\n get addRemoveLinks() {\n return this.data.get(\"addRemoveLinks\") === \"true\";\n }\n\n get multiple() {\n return this.maxFiles > 1;\n }\n}\n\nclass DirectUploadController {\n declare source: DropZoneController;\n\n declare directUpload: DirectUpload;\n declare hiddenInput: HTMLInputElement;\n declare file: CustomDropzoneFile;\n declare xhr: XMLHttpRequest;\n\n constructor(source: DropZoneController, file: CustomDropzoneFile) {\n this.directUpload = createDirectUpload(file, source.url, this);\n this.source = source;\n this.file = file;\n }\n\n start() {\n this.file.controller = this;\n this.hiddenInput = this.createHiddenInput();\n this.directUpload.create((error, attributes) => {\n if (error) {\n removeElement(this.hiddenInput);\n this.emitDropzoneError(error);\n } else {\n this.hiddenInput.value = attributes.signed_id;\n this.emitDropzoneSuccess();\n }\n });\n }\n\n createHiddenInput(): HTMLInputElement {\n const input = document.createElement(\"input\");\n input.type = \"hidden\";\n input.name = this.source.inputTarget.name;\n insertAfter(input, this.source.inputTarget);\n return input;\n }\n\n directUploadWillStoreFileWithXHR(xhr) {\n this.bindProgressEvent(xhr);\n this.emitDropzoneUploading();\n }\n\n bindProgressEvent(xhr: XMLHttpRequest) {\n this.xhr = xhr;\n this.xhr.upload.addEventListener(\"progress\", (event) => this.uploadRequestDidProgress(event));\n }\n\n uploadRequestDidProgress(event) {\n const progress = (event.loaded / event.total) * 100;\n (findElement(this.file.previewTemplate, \".dz-upload\") as HTMLElement).style.width = `${progress}%`;\n }\n\n emitDropzoneUploading() {\n this.file.status = Dropzone.UPLOADING;\n this.source.dropZone.emit(\"processing\", this.file);\n }\n\n emitDropzoneError(error) {\n this.file.status = Dropzone.ERROR;\n this.source.dropZone.emit(\"error\", this.file, error);\n this.source.dropZone.emit(\"complete\", this.file);\n }\n\n emitDropzoneSuccess() {\n this.file.status = Dropzone.SUCCESS;\n this.source.dropZone.emit(\"success\", this.file);\n this.source.dropZone.emit(\"complete\", this.file);\n }\n}\n\nfunction createDirectUploadController(source: DropZoneController, file: CustomDropzoneFile) {\n return new DirectUploadController(source, file);\n}\n\nfunction createDirectUpload(file: CustomDropzoneFile, url: string, controller: DirectUploadController) {\n return new DirectUpload(file, url, controller);\n}\n\nfunction createDropZone(controller: DropZoneController): Dropzone {\n // Other configuration options here https://docs.dropzone.dev/configuration/basics/configuration-options\n return new Dropzone(controller.element, {\n url: controller.url,\n headers: controller.headers,\n maxFiles: controller.maxFiles,\n maxFilesize: controller.maxFileSize,\n acceptedFiles: controller.acceptedFiles,\n addRemoveLinks: controller.addRemoveLinks,\n uploadMultiple: controller.multiple,\n autoQueue: false,\n });\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\n\n// Connects to data-controller=\"dynamic-select\"\nexport default class extends Controller {\n static targets = [\"select\", \"source\"];\n static values = {\n url: String,\n selectedAccountId: String,\n };\n\n declare selectTarget: HTMLSelectElement;\n declare sourceTarget: HTMLSelectElement;\n declare hasSourceTarget: boolean;\n declare selectedAccountIdValue: string;\n\n declare urlValue: string;\n\n connect() {\n if (this.hasSourceTarget) {\n this.setSelectOptions({ target: this.sourceTarget });\n }\n }\n\n setSelectOptions({ target }) {\n get(this.urlValue, {\n query: {\n target: this.selectTarget.id,\n postable: false,\n type: target.value,\n selected_account_id: this.selectedAccountIdValue,\n },\n responseKind: \"turbo-stream\",\n });\n\n this.dispatch(\"change\", { detail: { target: this.selectTarget, type: target.value } });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"form\"];\n\n declare formTarget: HTMLFormElement;\n declare hasFormTarget: boolean;\n declare preventNextSubmit: boolean;\n\n submit() {\n if (this.preventNextSubmit) {\n this.preventNextSubmit = false;\n return;\n }\n\n if (this.hasFormTarget) {\n this.formTarget.requestSubmit();\n } else {\n this.element.requestSubmit();\n }\n }\n\n preventSubmit() {\n this.preventNextSubmit = true;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\n\nimport cytoscape, { ElementDefinition } from \"cytoscape\";\n\ninterface Node {\n id: string;\n name: string;\n label: string;\n type: string;\n style: string;\n tax_classification: string;\n tax_classification_style: string;\n incorporated_on: string;\n accessible: boolean;\n}\n\ninterface Position {\n x: number;\n y: number;\n}\n\ninterface EdgeData {\n id: string;\n source: string;\n target: string;\n label: string;\n direction: string;\n bendPointPositions: Position[];\n}\n\ninterface Edge extends ElementDefinition {\n data: EdgeData;\n}\n\n// The extended Core module with plugins/extensions\ninterface ExtendedCore extends cytoscape.Core {\n domNode: () => void | undefined;\n edgeEditing: (input: string | object) => EdgeEditorInstance | undefined;\n}\n\ninterface EdgeEditorInstance {\n getAnchorsAsArray: (edge: cytoscape.EdgeSingular) => number[];\n initAnchorPoints: (edges: cytoscape.EdgeCollection) => void;\n}\n\n// Connects to data-controller=\"entity-graph\"\nexport default class extends Controller {\n static targets = [\"entityContainer\", \"nodeTemplate\"];\n\n static values = {\n nodes: Array,\n edges: Array,\n turboFrameId: String,\n entitiesUrl: String,\n entityGraphsUrl: String,\n positions: Object,\n };\n\n declare cy: ExtendedCore;\n declare entityContainerTarget: HTMLDivElement;\n declare entityGraphsUrlValue: string;\n declare positionsValue: object;\n declare edgesValue: Edge[];\n declare nodesValue: Node[];\n declare nodeTemplateTarget: HTMLTemplateElement;\n declare extensionsRegistered: boolean | undefined;\n\n connect() {\n // @ts-ignore\n this.cy = this.initializeGraph();\n\n this.cy.domNode(); // initialize cytoscape-dom-node\n\n this.addEventListeners(this.cy);\n\n // Initialize the edge editing library\n this.cy.edgeEditing({\n bendRemovalSensitivity: 8,\n initAnchorsAutomatically: true,\n bendPositionsFunction: (element) => {\n return element.data(\"bendPointPositions\");\n },\n // Edge editing is powered by Konva, which is a canvas library. Setting the zIndex to 0 here where the default\n // is 999. Documentation on the zIndex available here https://konvajs.org/docs/groups_and_layers/zIndex.html\n zIndex: 0,\n });\n }\n\n disconnect(): void {\n this.cy.removeAllListeners();\n }\n\n addEventListeners(cy) {\n // Events outlined here: https://js.cytoscape.org/#events\n cy.on(\"layoutready\", (_event: cytoscape.EventObject) => {\n this.setEdgePositions();\n });\n\n cy.on(\"tap\", \"node*\", (event: cytoscape.EventObject) => {\n const element = event.target.data(\"dom\") as HTMLDivElement;\n // The template(s) defined in the views have anchors with links\n const anchorElements = element.getElementsByTagName(\"a\");\n\n if (anchorElements.length === 1) {\n anchorElements[0].click();\n }\n });\n }\n\n initializeGraph() {\n const colorFunction = (element) => {\n if (element.data().direction === \"reverse\") {\n return \"#008698\";\n } else {\n return \"#888\";\n }\n };\n\n const sourceArrowFunction = (element) => {\n if (element.data().direction === \"reverse\") {\n return \"circle\";\n } else {\n return \"none\";\n }\n };\n\n return cytoscape({\n container: this.entityContainerTarget,\n elements: [...this.nodes(), ...this.edgesValue],\n style: [\n {\n selector: \"node\",\n style: {\n \"background-color\": \"transparent\",\n \"background-opacity\": 0,\n },\n },\n {\n selector: \"edge\",\n style: {\n width: 2,\n \"line-color\": colorFunction,\n \"target-arrow-color\": colorFunction,\n \"target-arrow-shape\": \"circle\",\n \"source-arrow-color\": colorFunction,\n \"source-arrow-shape\": sourceArrowFunction,\n \"curve-style\": \"segments\",\n },\n },\n {\n selector: \".view-label\",\n style: {\n label: \"data(label)\",\n color: \"white\",\n \"text-background-opacity\": 1,\n \"text-background-color\": colorFunction,\n \"text-background-shape\": \"roundrectangle\",\n \"text-background-padding\": \"4px\",\n \"font-size\": \"12px\",\n },\n },\n ],\n layout: {\n name: \"elk\",\n transform: (node, position) => {\n if (Object.keys(this.positionsValue).length) {\n return this.positionsValue[node.id()];\n } else {\n return position;\n }\n },\n // @ts-ignore\n elk: {\n algorithm: \"layered\",\n \"elk.direction\": \"DOWN\",\n \"nodeLabels.bk.fixedAlignment\": \"BALANCED\",\n \"elk.spacing.nodeNode\": 200, // Horizontal Spacing\n \"elk.layered.spacing.baseValue\": 80, // Vertical spacing\n },\n },\n userZoomingEnabled: true,\n wheelSensitivity: 0.2,\n minZoom: 0.4,\n maxZoom: 2.5,\n });\n }\n\n renderIfExists(content, template, content_tag, visibility_tag) {\n if (content) {\n const regex = new RegExp(content_tag, \"g\");\n return template.replace(regex, content);\n } else {\n const regex = new RegExp(visibility_tag, \"g\");\n return template.replace(regex, \"hidden\");\n }\n }\n\n createDomNodeFromTemplate(node: Node) {\n const div = document.createElement(\"div\");\n\n div.innerHTML = this.nodeTemplateTarget.innerHTML\n .replace(/ENTITY_NAME/g, node.name)\n .replace(/ENTITY_TYPE/g, node.label)\n .replace(/ENTITY_ID/g, node.id)\n .replace(/TAG_COLORS/g, node.style);\n\n div.innerHTML = this.renderIfExists(\n node.incorporated_on,\n div.innerHTML,\n \"INCORPORATED_ON\",\n \"INCORPORATED_VISIBILITY\",\n );\n\n div.innerHTML = this.renderIfExists(node.tax_classification, div.innerHTML, \"TAX_CLASSIFICATION\", \"TAX_VISIBILITY\");\n div.innerHTML = div.innerHTML.replace(/TAX_COLORS/g, node.tax_classification_style);\n\n // Remove links if the user cannot access the entity details\n if (!node.accessible) {\n div.querySelector(\"a\").remove();\n div.classList.add(\"opacity-60\");\n }\n\n return div;\n }\n\n nodes() {\n return this.nodesValue.map((node: Node) => {\n return {\n data: {\n id: `${node.id}`,\n dom: this.createDomNodeFromTemplate(node),\n },\n };\n });\n }\n\n savePositions(event) {\n const currentTarget = event.currentTarget;\n this.showLoader(currentTarget);\n\n const edgeEditor = this.cy.edgeEditing(\"get\");\n\n const positions = this.cy.nodes().reduce((obj, node) => {\n const id = node.id();\n return { ...obj, [id]: node.position() };\n }, []);\n\n const bendPointPositions = this.cy.edges().reduce((obj, edge) => {\n const id = edge.id();\n // As implied in the name, \"getAnchorsAsArray\" returns the anchor locations\n // as an array, however \"initAnchorPoints\" expects an array of objects with\n // x and y positions. So before saving positions on the server side, we convert\n // the array of numbers to an array x and y coordiantes.\n // e.g. from [1, 2, 3, 4] to\n // [\n // { x: 1, y: 2 },\n // { x: 3, y: 4 }\n // ]\n const positionsArray: number[] = edgeEditor.getAnchorsAsArray(edge);\n const coordinatesArray = this.convertArrayToCoordinates(positionsArray);\n\n return { ...obj, [id]: coordinatesArray };\n }, []);\n\n post(this.entityGraphsUrlValue, { body: { entity_graph: { nodes: positions, edges: bendPointPositions } } }).then(\n (response) => {\n this.hideLoader(currentTarget);\n\n if (response.statusCode === 200) {\n this.showIndicator(currentTarget, true);\n } else {\n this.showIndicator(currentTarget, false);\n }\n },\n );\n }\n\n toggleLabels(event: Event) {\n event.preventDefault();\n this.cy.edges().toggleClass(\"view-label\");\n }\n\n setEdgePositions() {\n const edgeEditorInstance = this.cy.edgeEditing(\"get\");\n\n if (edgeEditorInstance) {\n edgeEditorInstance.initAnchorPoints(this.cy.edges());\n }\n }\n\n convertArrayToCoordinates(positionsArray: number[]): Position[] {\n const coordinatesArray: Position[] = [];\n\n for (let idx = 0; idx < positionsArray.length; idx += 2) {\n const x = positionsArray[idx];\n const y = positionsArray[idx + 1];\n\n if (x && y) {\n coordinatesArray.push({ x, y });\n }\n }\n\n return coordinatesArray;\n }\n\n showLoader(currentTarget) {\n currentTarget.querySelector(\"span\").classList.add(\"hidden\");\n currentTarget.querySelector(\"div#layout_save_spinner\").classList.remove(\"hidden\");\n }\n\n hideLoader(currentTarget) {\n currentTarget.querySelector(\"div#layout_save_spinner\").classList.add(\"hidden\");\n }\n\n showIndicator(currentTarget, success) {\n const indicator = success ? \"layout_save_success\" : \"layout_save_failure\";\n\n currentTarget.querySelector(\"div#\" + indicator).classList.remove(\"hidden\");\n currentTarget.querySelector(\"div#\" + indicator).classList.add(\"visible\");\n\n setTimeout(() => {\n this.hideIndicator(currentTarget, success);\n }, 1000);\n }\n\n hideIndicator(currentTarget, success) {\n const indicator = success ? \"layout_save_success\" : \"layout_save_failure\";\n\n currentTarget.querySelector(\"div#\" + indicator).classList.remove(\"visible\");\n\n setTimeout(() => {\n currentTarget.querySelector(\"div#\" + indicator).classList.add(\"hidden\");\n currentTarget.querySelector(\"span\").classList.remove(\"hidden\");\n }, 500);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"entity-relationship-form\"\nexport default class extends Controller {\n static targets = [\n \"percentageBasedButton\",\n \"percentageBasedRelationshipRow\",\n \"relationshipTypeButton\",\n \"relationshipTypeInput\",\n \"units\",\n \"unitBasedButton\",\n \"unitBasedRelationshipRow\",\n ];\n\n static values = {\n relationshipTypeClassesToAdd: { type: String, default: \"bg-cyan-600 focus:ring-cyan-500 text-white pointer-events-none\" },\n relationshipTypeClassesToRemove: { type: String, default: \"btn-white\" }\n }\n\n declare percentageBasedButtonTarget: HTMLButtonElement;\n declare percentageBasedRelationshipRowTargets: HTMLElement[];\n declare relationshipTypeButtonTargets: HTMLButtonElement[];\n declare relationshipTypeClassesToAddValue: string;\n declare relationshipTypeClassesToRemoveValue: string;\n declare relationshipTypeInputTargets: HTMLInputElement[];\n declare unitsTargets: HTMLInputElement[];\n declare unitBasedButtonTarget: HTMLButtonElement;\n declare unitBasedRelationshipRowTargets: HTMLElement[];\n\n percentageReadOnlyTargetConnected() {\n this.updatePercentageReadOnlyValues();\n }\n\n showRelationshipRow(target) {\n target.classList.remove('hidden');\n const input = target.querySelector(\"input[type='number']\") as HTMLInputElement;\n input.removeAttribute('disabled');\n }\n\n hideRelationshipRow(target) {\n target.classList.add('hidden');\n const input = target.querySelector(\"input[type='number']\") as HTMLInputElement;\n input.setAttribute('disabled', '');\n }\n\n showUnitBasedRelationshipRows() {\n this.unitBasedRelationshipRowTargets.forEach(target => this.showRelationshipRow(target));\n this.percentageBasedRelationshipRowTargets.forEach(target => this.hideRelationshipRow(target));\n this.relationshipTypeInputTargets.forEach(target => target.value = \"unit_based\");\n }\n\n showPercentageBasedRelationshipRows() {\n this.unitBasedRelationshipRowTargets.forEach(target => this.hideRelationshipRow(target));\n this.percentageBasedRelationshipRowTargets.forEach(target => this.showRelationshipRow(target));\n this.relationshipTypeInputTargets.forEach(target => target.value = \"percentage_based\");\n }\n\n toggleRelationshipType(event) {\n this.relationshipTypeButtonTargets.forEach(target => {\n if (target === event.target) {\n target.setAttribute('disabled', '');\n target.classList.remove(...this.relationshipTypeClassesToRemoveValue.split(' '));\n target.classList.add(...this.relationshipTypeClassesToAddValue.split(' '));\n } else {\n target.removeAttribute('disabled');\n target.classList.remove(...this.relationshipTypeClassesToAddValue.split(' '));\n target.classList.add(...this.relationshipTypeClassesToRemoveValue.split(' '));\n }\n });\n\n if (event.target === this.unitBasedButtonTarget) {\n this.showUnitBasedRelationshipRows();\n } else if (event.target === this.percentageBasedButtonTarget) {\n this.showPercentageBasedRelationshipRows();\n }\n }\n\n toggleRelationshipTypeOnNewRelationshipRow() {\n if (this.unitBasedButtonTarget.hasAttribute('disabled')) {\n this.showRelationshipRow(this.unitBasedRelationshipRowTargets.at(-1))\n this.hideRelationshipRow(this.percentageBasedRelationshipRowTargets.at(-1))\n this.relationshipTypeInputTargets.at(-1).value = \"unit_based\";\n } else if (this.percentageBasedButtonTarget.hasAttribute('disabled')) {\n this.showRelationshipRow(this.percentageBasedRelationshipRowTargets.at(-1))\n this.hideRelationshipRow(this.unitBasedRelationshipRowTargets.at(-1))\n this.relationshipTypeInputTargets.at(-1).value = \"percentage_based\";\n }\n }\n\n updatePercentageReadOnlyValues() {\n const shareInputs = this.unitsTargets.map(input => parseInt(input.value));\n const totalShares = shareInputs.reduce((accumulator, currentValue) => {\n return accumulator + (isNaN(currentValue) ? 0 : currentValue);\n }, 0);\n\n this.unitBasedRelationshipRowTargets.forEach((row, index) => {\n const percentageReadOnlyElement = row.querySelector(\n \"[data-entity-relationship-form-target='percentageReadOnly']\"\n ) as HTMLInputElement;\n const shareInput = shareInputs[index];\n const percentage = isNaN(shareInput) || totalShares === 0 ? 0 : ((shareInput / totalShares) * 100).toFixed(6);\n percentageReadOnlyElement.value = `${percentage}%`;\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\nimport {\n FinicityConnect,\n ConnectEventHandlers,\n ConnectOptions,\n ConnectDoneEvent,\n ConnectCancelEvent,\n ConnectErrorEvent,\n} from \"@finicity/connect-web-sdk\";\n\nexport default class extends Controller {\n static targets = [\"connectButton\", \"connectButtonIcon\", \"loadingIcon\"];\n static values = { connectUrl: String, modalOpen: { type: Boolean, default: false } };\n\n declare connectButtonTarget: HTMLButtonElement;\n declare connectButtonIconTarget: SVGElement;\n declare loadingIconTarget: SVGElement;\n declare connectUrlValue: string;\n declare modalOpenValue: boolean;\n\n connect() {\n document.addEventListener(\"turbo:before-stream-render\", this.handleTurboBeforeStreamRender.bind(this));\n }\n\n disconnect() {\n FinicityConnect.destroy();\n document.removeEventListener(\"turbo:before-stream-render\", this.handleTurboBeforeStreamRender.bind(this));\n }\n\n // Prevent Turbo from refreshing the page when the connect modal is open\n handleTurboBeforeStreamRender(event: Event) {\n if (this.modalOpenValue) {\n event.preventDefault();\n }\n }\n\n async makeConnection() {\n this.showLoader();\n\n const jsonResponse = await this.generateConnectUrl();\n const connectUrl = jsonResponse.link;\n\n if (jsonResponse.error) {\n console.error(`Error generating Connect URL. ${jsonResponse.error}`);\n this.hideLoader();\n return;\n } else if (!connectUrl) {\n console.error(`Error generating Connect URL. No link returned.`);\n this.hideLoader();\n return;\n }\n\n const connectEventHandlers: ConnectEventHandlers = {\n onDone: (_event: ConnectDoneEvent) => {\n this.element.requestSubmit();\n this.modalOpenValue = false;\n },\n onCancel: (_event: ConnectCancelEvent) => {\n this.modalOpenValue = false;\n },\n onError: (event: ConnectErrorEvent) => {\n this.modalOpenValue = false;\n console.error(event);\n },\n onLoad: () => {\n this.modalOpenValue = true;\n },\n };\n\n const connectOptions: ConnectOptions = {\n overlay: \"rgba(199,201,199, 0.5)\",\n };\n\n FinicityConnect.launch(connectUrl, connectEventHandlers, connectOptions);\n }\n\n async generateConnectUrl(): Promise<{ link?: string; error?: string }> {\n const response = await post(this.connectUrlValue, { body: {}, responseKind: \"json\" });\n\n return response.json;\n }\n\n modalOpenValueChanged(value: boolean, _previous: boolean) {\n if (value) {\n this.showLoader();\n } else {\n this.hideLoader();\n }\n }\n\n showLoader() {\n this.connectButtonTarget.disabled = true;\n this.connectButtonIconTarget.classList.add(\"hidden\");\n this.loadingIconTarget.classList.remove(\"hidden\");\n }\n\n hideLoader() {\n this.connectButtonTarget.disabled = false;\n this.connectButtonIconTarget.classList.remove(\"hidden\");\n this.loadingIconTarget.classList.add(\"hidden\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { Modal, modalBackdrop, modalPlacement } from 'flowbite';\n\n// Connects to data-controller=\"flowbite-modal\"\nexport default class extends Controller {\n static values = {\n backdrop: {\n type: String,\n default: \"dynamic\" as modalBackdrop,\n },\n }\n\n declare backdropValue: \"dynamic\" | \"static\";\n\n static targets = ['modal']\n\n declare modalTarget: HTMLElement;\n declare hasModalTarget: boolean;\n\n declare modal: Modal | undefined;\n\n connect() {}\n\n hideModal(_event: Event) {\n this.modal?.hide();\n\n this.cleanup();\n }\n\n showModal(_event: Event) {\n this.modal?.show();\n }\n\n modalTargetConnected(target: HTMLElement) {\n // set the modal menu element\n const targetEl = target;\n\n // options with default values\n const options = {\n placement: \"center\" as modalPlacement,\n backdrop: this.backdropValue as modalBackdrop,\n backdropClasses: \"backdrop-blur-sm bg-gray-900/50 fixed inset-0 z-40\",\n closable: true,\n onHide: () => {},\n onShow: () => {},\n onToggle: () => {},\n };\n\n // instance options object\n const instanceOptions = {\n id: this.modalTarget.id,\n override: true,\n };\n\n this.modal = new Modal(targetEl, options, instanceOptions);\n }\n\n cleanup() {\n // this is a workaround since it looks like this is a current issue with flowbite and turbo. Ref: https://github.com/themesberg/flowbite/issues/545, https://github.com/themesberg/flowbite/issues/551, https://github.com/themesberg/flowbite/issues/579\n document.querySelectorAll(\"[modal-backdrop]\").forEach((el: HTMLElement) => {\n el?.remove();\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { TurboFrameElement } from \"@hotwired/turbo\";\n\n// Connects to data-controller=\"frame-loader\"\nexport default class extends Controller {\n static values = {\n path: String,\n };\n\n static targets = [\"spinner\"];\n\n declare pathValue: string;\n declare spinnerTarget: HTMLElement;\n declare hasSpinnerTarget: boolean;\n\n connect() {}\n\n loadFrame(event: Event) {\n if (event.target instanceof HTMLElement) {\n event.target.classList.add(\"hidden\");\n }\n\n if (this.hasSpinnerTarget) {\n this.spinnerTarget.classList.remove(\"hidden\");\n }\n\n this.element.loaded = \"lazy\";\n this.element.src = this.pathValue;\n }\n\n reloadFrame() {\n this.element.reload();\n }\n}\n","import { ValueGetterParams } from \"ag-grid-enterprise\";\n\nconst convertColToNumber = (params: ValueGetterParams, col: string) => {\n if (!params.node.data) {\n return 0;\n }\n\n const val = Number(params.node.data[col]);\n\n if (val && !Number.isNaN(val)) {\n return val;\n } else {\n return 0;\n }\n};\n\nexport const aggColumnValues = (params: ValueGetterParams, cols: string[]) => {\n return cols.reduce((acc, col) => acc + convertColToNumber(params, col), 0);\n};\n\nexport const getCheckboxValues = (checkboxes: HTMLInputElement[]) => {\n const checkboxesIds = []\n checkboxes.forEach((checkbox) => {\n if(checkbox.checked) checkboxesIds.push(checkbox.value)\n })\n return checkboxesIds;\n};\n\nexport const setOptionsCheckboxValue = (checkboxes: HTMLInputElement[], name: string, value: boolean) => {\n const checkbox = checkboxes.find(target => target.name === name);\n if (checkbox) {\n checkbox.checked = value\n }\n};\n\nexport const setCheckboxValues = (checkboxes: HTMLInputElement[], selectedCheckboxes: number[]) => {\n checkboxes.forEach((checkbox) => {\n if(selectedCheckboxes.includes(parseInt(checkbox.value))) {\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event('change'));\n }\n });\n};\n\nexport const setSelectValues = (select, selectedIds: number[]) => {\n if (select.tomselect) {\n select.tomselect.setValue(selectedIds)\n } else {\n select.options.forEach((option) => {\n if (selectedIds.includes(parseInt(option.value))) {\n option.selected = true\n }\n })\n }\n};\n\nexport const getSelectValues = (select: HTMLSelectElement) => {\n const options = select && select.options;\n\n const selectedOptions = Array.from(options).filter((opt: HTMLOptionElement) => opt.selected);\n const result = selectedOptions.map((opt: HTMLOptionElement) => opt.value || opt.text);\n\n return result;\n};\n","import { post, get } from \"@rails/request.js\";\nimport { getSelectValues } from \"./index\";\nimport { ReportContext } from \"../../types\";\nimport { ValueGetterParams } from \"ag-grid-enterprise\";\n\nexport function addAutoLoadParamToUrl() {\n // Skip if the url has the auto_load or report_template_id params\n if (window.location.search.includes(\"auto_load\") || window.location.search.includes(\"report_template_id\")) {\n return;\n }\n\n const url = new URLSearchParams(window.location.search);\n url.set(\"auto_load\", \"true\");\n window.history.replaceState({}, document.title, window.location.origin + window.location.pathname + \"?\" + url);\n}\n\nexport function calculatePercentChangeTotal({ priorPeriodTotal, changeTotal }) {\n let percentChangeTotal;\n\n if (!priorPeriodTotal || priorPeriodTotal == 0) {\n percentChangeTotal = \"N/A\";\n } else {\n percentChangeTotal = changeTotal / Math.abs(priorPeriodTotal);\n }\n\n return percentChangeTotal;\n}\n\nexport function validateDateSelected(context: ReportContext) {\n const parentNode = context.dateRangeTarget.parentNode as HTMLElement;\n\n if (context.endDateTarget.value === \"\") {\n context.dateErrorsTarget.classList.remove(\"hidden\");\n context.dateErrorsTarget.innerText = \"Please select a reporting period\";\n parentNode.classList.add(\"border-2\", \"border-rose-500\", \"rounded-md\");\n context.startDateTarget.classList.add(\"border-2\", \"border-rose-500\", \"rounded-md\");\n context.endDateTarget.classList.add(\"border-2\", \"border-rose-500\", \"rounded-md\");\n context.gridApi.showNoRowsOverlay();\n\n return false;\n } else {\n if (!context.dateErrorsTarget.classList.contains(\"hidden\")) {\n context.dateErrorsTarget.classList.add(\"hidden\");\n }\n parentNode.classList.remove(\"border-2\", \"border-rose-500\", \"rounded-md\");\n context.startDateTarget.classList.remove(\"border-2\", \"border-rose-500\", \"rounded-md\");\n context.endDateTarget.classList.remove(\"border-2\", \"border-rose-500\", \"rounded-md\");\n }\n\n return true;\n}\n\n// Sets the date and options display in the rendered report\nexport function setDateAndAlertDisplay(context, data) {\n if (context.endDateTarget.value) {\n context.dateDisplayTarget.innerText = context.reportDateHeader();\n context.dateDisplayTarget.classList.remove(\"hidden\");\n }\n\n const optionsArray = [];\n context.optionTargets.forEach((option) => {\n if (option.checked && option.dataset.alertName) {\n optionsArray.push(option.dataset.alertName);\n }\n });\n\n let alertsArray = [];\n\n if (optionsArray.length > 0) {\n alertsArray.push(`Includes ${optionsArray.join(\", \")}`);\n }\n\n if (data && data[\"alerts\"]) {\n alertsArray = alertsArray.concat(data.alerts);\n }\n\n if (alertsArray.length > 0) {\n context.alertDisplayTarget.innerHTML = alertsArray\n .map(\n (alert) =>\n `${alert}`,\n )\n .join(\" \");\n context.alertDisplayTarget.classList.remove(\"hidden\");\n } else {\n context.alertDisplayTarget.innerHTML = \"\";\n context.alertDisplayTarget.classList.add(\"hidden\");\n }\n}\n\nexport function clearNotices() {\n const reportNoticesElement = document.querySelector(\"#report_notices\");\n if (reportNoticesElement) {\n document.querySelector(\"#report_notices\").innerHTML = \"\";\n }\n}\n\nexport async function requestReportData(body) {\n clearNotices();\n const url = `${window.location.origin + window.location.pathname}_data`;\n const result = await post(url, {\n body: body,\n responsekind: \"json\",\n });\n return result;\n}\n\nexport async function processReportDataResponse(context: ReportContext, response, callback) {\n if (response.ok) {\n hideErrorOverlay(context);\n const data = await response.json;\n return callback(data);\n } else if (response.statusCode === 500) {\n showErrorOverlay(context);\n } else {\n const data = await response.json;\n renderReportNotices(context, data);\n }\n}\n\nfunction createErrorOverlay(): HTMLElement {\n const overlay = document.createElement(\"div\");\n overlay.id = \"error-overlay\";\n overlay.className = \"flex\";\n const overlayTemplate = document.getElementById(\"error-overlay-template\") as HTMLTemplateElement;\n overlay.innerHTML = overlayTemplate.content.firstElementChild.outerHTML;\n return overlay;\n}\n\nfunction showErrorOverlay(context: ReportContext) {\n let overlay = document.getElementById(\"error-overlay\");\n\n if (!overlay) {\n overlay = createErrorOverlay();\n } else {\n overlay.remove();\n }\n\n if (context.gridTarget) {\n context.gridTarget.style.position = \"relative\";\n if (!context.gridTarget.contains(overlay)) {\n context.gridTarget.appendChild(overlay);\n }\n overlay.style.display = \"flex\";\n }\n}\n\nfunction hideErrorOverlay(context: ReportContext) {\n const overlay = document.getElementById(\"error-overlay\");\n\n if (overlay && context.gridTarget.contains(overlay)) {\n context.gridTarget.removeChild(overlay);\n }\n}\n\nfunction renderReportNotices(context: ReportContext, data) {\n context.gridApi.showNoRowsOverlay();\n const generalNoticeElement = document.querySelector(\"#general_notice\");\n if (generalNoticeElement) {\n generalNoticeElement.classList.remove(\"hidden\");\n document.querySelector(\"#general_notice p\").innerHTML = data.errors.join(\"
\");\n }\n}\n\nexport function validateEntitySet(context: ReportContext) {\n if (getSelectValues(context.ledgersTarget).filter((v) => v).length === 0) {\n context.ledgerErrorsTarget.classList.remove(\"hidden\");\n context.ledgerErrorsTarget.innerText = \"This field is required\";\n context.ledgersTarget.nextElementSibling.classList.add(\"border-2\", \"border-rose-500\", \"rounded-md\");\n\n context.gridApi.showNoRowsOverlay();\n return false;\n } else {\n if (!context.ledgerErrorsTarget.classList.contains(\"hidden\")) {\n context.ledgerErrorsTarget.classList.add(\"hidden\");\n }\n context.ledgersTarget.nextElementSibling.classList.remove(\"border-2\", \"border-rose-500\", \"rounded-md\");\n }\n\n return true;\n}\n\nexport function hasOption(context: ReportContext, optionName: string): boolean {\n return context.optionTargets.some((option) => option.name === optionName);\n}\n\nexport function getOptionState(context: ReportContext, optionName: string): boolean {\n return context.optionTargets.find((option) => option.name === optionName).checked;\n}\n\nexport function numberValueGetter(params: ValueGetterParams) {\n const columnField = params.colDef.field;\n\n // Coerce strings to numbers in order for the aggregation function to work\n if (params.data) {\n const val = Number(params.data[columnField]);\n\n if (Number.isNaN(val)) {\n return null;\n } else {\n return val;\n }\n }\n}\n\nexport function updateBreadcrumb(reportTemplateId: string | null, element: HTMLElement) {\n const queryParams = new URLSearchParams(window.location.search);\n queryParams.set(\"report_template_id\", reportTemplateId);\n queryParams.set(\"report_type\", element.dataset.railsAction);\n\n get(`/reporting/featured_reports/breadcrumb?${queryParams.toString()}`, {\n responseKind: \"turbo-stream\",\n });\n}\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n\n return true;\n}\n\nexport function shouldRefreshGrouping(\n existingRowData: { id: string; accountBreadCrumbs: string[] }[],\n newRowData: { id: string; accountBreadCrumbs: string[] }[],\n): boolean {\n // Create a map of existing data for quick lookup\n const existingDataMap = new Map(existingRowData.map((row) => [row.id, row]));\n\n for (const newRow of newRowData) {\n const existingRow = existingDataMap.get(newRow.id);\n\n // If the row doesn't exist in the existing data, we need to refresh\n if (!existingRow) {\n return true;\n }\n\n // Compare accountBreadCrumbs\n if (!arraysEqual(existingRow.accountBreadCrumbs, newRow.accountBreadCrumbs)) {\n return true;\n }\n }\n\n // If we've made it this far, no changes were found\n return false;\n}\n","import { ReportContext } from \"../types\";\nimport { parseDateRangeOption } from \"./date_range_option_parser\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\nexport function prepareDateRangeOptions(options) {\n if (options?.date_range) {\n delete options.start_date;\n delete options.end_date;\n } else {\n delete options.date_range;\n }\n return options;\n}\n\nexport function addRelativeDatesToParams(options) {\n if (options?.date_range) {\n const parsedDates = parseDateRangeOption(options.date_range);\n const startDate = parsedDates?.startDate?.toISOString()?.split(\"T\")[0];\n const endDate = parsedDates?.endDate?.toISOString()?.split(\"T\")[0];\n options.start_date = startDate;\n options.end_date = endDate;\n }\n return options;\n}\n\nexport function getRelativeDates(context: ReportContext) {\n if (context.hasDateRangeTarget && context.dateRangeTarget.value !== \"\") {\n const parsedDates = parseDateRangeOption(context.dateRangeTarget.value);\n const startDate = parsedDates?.startDate?.toISOString()?.split(\"T\")[0];\n const endDate = parsedDates?.endDate?.toISOString()?.split(\"T\")[0];\n\n return {\n start_date: startDate,\n end_date: endDate,\n };\n }\n\n return {\n start_date: context.hasStartDateTarget ? context.startDateTarget.value : null,\n end_date: context.hasEndDateTarget ? context.endDateTarget.value : null,\n };\n}\n\nexport function loadDateRange(values, context: ReportContext) {\n const dateRangeTomSelect = (context.dateRangeTarget as TomInput)?.tomselect;\n // this is here because when you load a report, click Run Report and then refresh the page, TomSelect doesn't load in time.\n if (dateRangeTomSelect) {\n dateRangeTomSelect.setValue(values.date_range);\n } else {\n context.dateRangeTarget.value = values.date_range;\n }\n}\n\nexport function loadDateInputs(values, context: ReportContext) {\n if (context.hasDateRangeTarget && values.date_range) {\n loadDateRange(values, context);\n if (context.hasStartDateTarget) context.startDateTarget.value = getRelativeDates(context).start_date;\n if (context.hasEndDateTarget) context.endDateTarget.value = getRelativeDates(context).end_date;\n } else {\n if (context.hasStartDateTarget) context.startDateTarget.value = values.start_date;\n if (context.hasEndDateTarget) context.endDateTarget.value = values.end_date;\n }\n}\n","import { Turbo } from \"@hotwired/turbo-rails\";\nimport { post, put, get } from \"@rails/request.js\";\nimport { requestReportData, processReportDataResponse } from \"./utils\";\nimport { ReportContext } from \"../../types\";\nimport { addRelativeDatesToParams } from \"../relative_dates\";\n\nexport async function saveReportTemplate(\n reportTemplateData: { report_type: string; report_options: object },\n reportTemplateType: string,\n reportTemplateName: string,\n) {\n const response = await post(\"/reporting/report_templates\", {\n body: {\n report_template: {\n name: reportTemplateName,\n report_type: reportTemplateType,\n options: reportTemplateData.report_options,\n },\n },\n responseKind: \"turbo-stream\",\n });\n\n if (response.statusCode === 201) return Turbo.visit(\"/reporting/saved_reports\");\n\n if (response.statusCode === 422) {\n const responseText = await response.text;\n\n Turbo.renderStreamMessage(responseText);\n }\n}\n\nexport function updateSavedReportTemplate(\n reportTemplateData: { report_type: string; report_options: object },\n reportTemplateId: string,\n) {\n if (reportTemplateId) {\n put(`/reporting/report_templates/${reportTemplateId}`, {\n body: {\n report_template: {\n report_type: reportTemplateData.report_type,\n options: reportTemplateData.report_options,\n },\n },\n responseKind: \"turbo-stream\",\n });\n }\n}\n\nexport function processSavedReport(context: ReportContext, savedReportId) {\n requestSavedReport(savedReportId)\n .then((response) => {\n if (response.ok) {\n return response.json;\n } else {\n throw new Error(\"Response not ok.\");\n }\n })\n .then((savedReport) => {\n redirectToCorrectReport(savedReport.report_type);\n\n loadSavedReportGridData(context, new Event(\"autoload:saved_report\"), savedReport);\n })\n .catch((error) => {\n console.error(error);\n });\n}\n\nexport async function loadSavedReportGridData(context: ReportContext, _event: Event, savedReport = null) {\n savedReport.options = addRelativeDatesToParams(savedReport.options);\n\n // In order to set the ag grid state, we need to destroy the grid first\n if (context.gridApi) {\n context.gridApi.destroy();\n }\n\n context.loadAgGridState(savedReport.options.ag_grid_state);\n context.createGrid();\n\n context.totalCols.clear();\n context.gridApi.setGridOption(\"loading\", true);\n\n context.loadValuesToInputs(savedReport.options);\n sessionStorage.setItem(context.sessionStorageKey(\"report_options\"), JSON.stringify(savedReport?.options));\n\n requestReportData(savedReport.options)\n .then((response) => {\n processReportDataResponse(context, response, (data) => {\n context.renderGrid(data, true, savedReport.options);\n });\n })\n .catch((error) => {\n console.error(error);\n });\n}\n\nexport async function requestSavedReport(savedReportId) {\n const savedReport = await get(`/reporting/report_templates/${savedReportId}`, {\n responseKind: \"json\",\n });\n return savedReport;\n}\n\nexport function redirectToCorrectReport(reportType) {\n if (!window.location.pathname.includes(reportType)) {\n Turbo.visit(\"/reporting/featured_reports/\" + reportType + window.location.search);\n }\n}\n","import {\n ExcelExportParams,\n CellClassParams,\n ProcessCellForExportParams,\n ExcelRow,\n ProcessHeaderForExportParams,\n RowNode,\n} from \"ag-grid-enterprise\";\nimport { ExcelStyle } from \"ag-grid-community\";\nimport { isGroupFooter, isSectionHeader, isSectionFooter, isGroupHeader } from \"./node_helpers\";\nimport { formatDateForDisplay } from \"./formatters\";\nimport { ServerProvidedColDef, ReportType, ReportOption } from \"../../types\";\n\nconst REPORT_LABELS: Record = {\n income_statement: 'Income Statement',\n balance_sheet: 'Balance Sheet',\n consolidated: 'Consolidated Balance Sheet',\n net_worth: 'Net Worth Statement',\n trial_balance: 'Trial Balance',\n cash_flow_statement: 'Cash Flow Statement',\n general_ledger: 'General Ledger',\n \"sumit-report\": 'Report'\n};\n\ninterface ConsolidationMetadataEntry {\n text: string;\n value: string;\n}\n\nexport const defaultExportParams: ExcelExportParams = {\n // This callback is called on all cells before they are exported. We use it to format the values based on whether\n // the cell is a group header or footer.\n processCellCallback: (params: ProcessCellForExportParams) => {\n const node = params.node as unknown as RowNode;\n const column = params.column;\n const colDef = column.getColDef();\n const innerRenderer = colDef.cellRendererParams?.innerRenderer;\n\n if (innerRenderer === \"accountCellRenderer\" || innerRenderer === \"flattenedAccountCellRenderer\") {\n // For group headers and footers, AG Grid renders the full path in the value.\n // as an example for the \"110000 - Current Assets\" header, it renders: \"Sources of Cash -> 100000 - Assets -> 110000 - Current Assets\".\n // For the footer it renders something like \"Total -> Sources of Cash -> 100000 - Assets -> 110000 - Current Assets\"\n // Here we get only the last value. In this example, it would be \"110000 - Current Assets\"\n const value = params.value ? params.value : node.key;\n const breadcrumbArray = value.split(\" -> \");\n\n if (isGroupFooter(node)) {\n return `Total ${breadcrumbArray[breadcrumbArray.length - 1]}`;\n } else {\n // For group headers, AG Grid sometimes inserts \" -> \" between the group header and the value. We remove it here.\n return `${breadcrumbArray[breadcrumbArray.length - 1]}`;\n }\n }\n\n if (!node.expanded && node.displayed) {\n return params.value;\n }\n\n const number = Number(params.value);\n\n if (isGroupHeader(node)) {\n const a_one_space_string_so_aggrid_does_not_insert_other_header_value = \" \";\n return a_one_space_string_so_aggrid_does_not_insert_other_header_value;\n } else if (isGroupFooter(node)) {\n if (isNaN(number) || params.value?.toString() == \"N/A\") {\n return params.value;\n } else {\n return number;\n }\n }\n\n if (isNaN(number) || params.value?.toString() == \"N/A\") {\n return params.value;\n }\n\n return params.value;\n },\n // This callback is called on all header cells before they are exported. We use it to format the values based on whether\n // there is consolidation metadata for the column.\n processHeaderCallback: (params: ProcessHeaderForExportParams): string => {\n const colDef = params.column.getColDef() as unknown as ServerProvidedColDef;\n const consolidationMetadata = colDef.metadata?.consolidationMetadata ||\n colDef.context?.metadata?.consolidationMetadata;\n const headerName = params.column.getColDef().headerName;\n\n if (!consolidationMetadata) {\n return headerName;\n }\n\n const metadataEntries = Object.values(consolidationMetadata)\n .map((entry: ConsolidationMetadataEntry) => `${entry.text}: ${entry.value}`)\n .join('\\n');\n\n return `${headerName}\\n${metadataEntries}`;\n },\n};\n\nexport const defaultGLExportParams: ExcelExportParams = {\n // This callback is called on all cells before they are exported. We use it to format the values\n processCellCallback: (params: ProcessCellForExportParams) => {\n const node = params.node as unknown as RowNode;\n const column = params.column;\n const colDef = column.getColDef();\n const innerRenderer = colDef.cellRendererParams?.innerRenderer;\n const field = colDef.field;\n\n // We don't want to show any values for expanded group headers\n if (node.level === 1 && node.expanded && !isGroupFooter(node)) {\n return \" \";\n }\n\n if (field === \"accountCode\") {\n if (params.value == null || params.value === undefined) {\n return \" \";\n } else {\n return `${params.value.group}: ${params.value.name}`;\n }\n }\n\n if (field === \"tags\") {\n if (params.value == null || params.value === undefined) {\n return \" \";\n } else {\n if (Array.isArray(params.value)) {\n return params.value.map(tag => `${tag.group}: ${tag.name}`).join(\"; \");\n } else {\n return params.value.name;\n }\n }\n }\n\n if (field === \"effectiveAt\" && params.value === undefined || params.value === null) {\n const value = params.value ? params.value : node.key;\n\n if ((isGroupFooter(node))) {\n const breadcrumbArray = value.split(\" -> \");\n\n if (breadcrumbArray.length > 1) {\n return `Total ${breadcrumbArray[breadcrumbArray.length - 1]}`;\n }\n\n return `Total ${value}`;\n }\n }\n\n if (field === \"entity\" && (params.value === undefined || params.value === null)) {\n return node.parent.key;\n }\n\n if (field === \"account\" && (params.value === undefined || params.value === null)) {\n return node.key;\n }\n\n if (innerRenderer === \"GLAccountCellRenderer\") {\n const value = params.value ? params.value : node.key;\n\n const breadcrumbArray = value.split(\" -> \");\n\n if (breadcrumbArray.length > 1) {\n return `Total ${breadcrumbArray[breadcrumbArray.length - 1]}`;\n }\n\n return `Total ${value}`;\n }\n\n if (!node.expanded && node.displayed) {\n return params.value;\n }\n\n // This number formatting is required for Roo to format Excel cells as floats\n if (colDef.cellDataType === \"number\") {\n const number = Number(params.value);\n\n return number;\n } else {\n return params.value;\n }\n },\n};\n\nfunction buildIndentationStyles(level: number): ExcelStyle[] {\n if (level > 0) {\n const styles: ExcelStyle[] = [];\n\n for (let i = 1; i <= level; i++) {\n styles.push({\n id: `indent-${i}`,\n alignment: {\n indent: i,\n },\n // note, dataType: 'String' required to ensure that numeric values aren't right-aligned\n dataType: \"String\",\n });\n }\n\n return styles;\n }\n\n return [];\n}\n\nexport const excelStyles: ExcelStyle[] = [\n ...buildIndentationStyles(5),\n {\n id: \"header\",\n interior: {\n pattern: \"Solid\",\n color: \"#015965\",\n },\n font: {\n size: 14,\n color: \"#ffffff\",\n },\n alignment: {\n vertical: \"Center\",\n },\n },\n {\n id: \"report-header\",\n dataType: \"String\",\n font: {\n bold: true,\n size: 18,\n },\n },\n {\n id: \"section-total\",\n borders: {\n borderTop: {\n color: \"black\",\n lineStyle: \"Continuous\",\n weight: 1,\n },\n },\n font: {\n bold: true,\n size: 13,\n },\n },\n {\n id: \"section-subtotal\",\n borders: {\n borderTop: {\n color: \"black\",\n lineStyle: \"Continuous\",\n weight: 1,\n },\n },\n font: {\n bold: true,\n size: 12,\n },\n },\n {\n id: \"section\",\n interior: {\n pattern: \"Solid\",\n color: \"#e5e7eb\",\n },\n font: {\n bold: true,\n size: 13,\n },\n },\n {\n id: \"number-cell\",\n dataType: \"Number\",\n numberFormat: {\n format: \"#,##0.00\",\n },\n },\n {\n id: \"percentage-cell\",\n numberFormat: {\n format: \"###,##0.00%\",\n },\n },\n];\n\nexport function getClasses(params: CellClassParams): string[] | string {\n const node = params.node as unknown as RowNode;\n const classes = [`indent-${node.level}`];\n\n const metadata = node.data?.metadata;\n if (metadata?.generated_total_row) {\n classes.push(\"section-total\");\n } else if (isSectionHeader(node)) {\n classes.push(\"section\");\n } else if (isSectionFooter(node) || node.isRowPinned()) {\n classes.push(\"section-total\");\n } else if (node.footer) {\n classes.push(\"section-subtotal\");\n }\n return classes;\n}\n\nexport function getClassesForAccounts(params: CellClassParams): string[] | string {\n return getClasses(params);\n}\n\nexport function getClassesForCells(params: CellClassParams): string[] | string {\n const node = params.node as unknown as RowNode;\n const classes = [];\n\n // Ensure the cell is not a header and is a number or is a number cell of a collapsed row with total for children of them\n const isNumber = !isNaN(Number(params.value)) && params.colDef.cellDataType === \"number\";\n const isCollapsedRow = !node.expanded && node.displayed;\n if ((isNumber && !isGroupHeader(node)) || (isNumber && isCollapsedRow)) {\n classes.push(\"number-cell\");\n }\n\n if (!isNaN(Number(params.value)) || params.colDef.cellDataType === \"percentage\") {\n classes.push(\"ag-right-aligned-cell\");\n }\n\n if (params.colDef.cellDataType === \"percentage\") {\n classes.push(\"percentage-cell\");\n }\n\n if (isGroupFooter(node) || node.isRowPinned()) {\n classes.push(\"number-cell-bold\");\n }\n\n const metadata = node.data?.metadata;\n if (metadata?.generated_total_row) {\n classes.push(\"section-total\");\n } else if (isSectionHeader(node)) {\n classes.push(\"section\");\n } else if (isSectionFooter(node) || node.isRowPinned()) {\n classes.push(\"section-total\");\n } else if (node.footer) {\n classes.push(\"section-subtotal\");\n }\n\n return classes;\n}\n\nexport function headerRows(\n reportType: ReportType,\n reportDate: Date,\n startDate: string | null,\n endDate: string | null,\n entityNames: string[],\n options: ReportOption[]\n): ExcelRow[] {\n const reportLabel = REPORT_LABELS[reportType] || 'Report';\n const entityNamesLabel = entityNames.length > 0 ? entityNames.join(', ') : 'All Entities';\n const entitiesLabel = `Entities: ${entityNamesLabel}`;\n const reportDateLabel = formatDateForDisplay(reportDate);\n\n let periodLabel = 'All Dates';\n if (startDate && endDate) {\n const isPeriodReport = ['income_statement', 'cash_flow_statement', 'general_ledger'].includes(reportType);\n periodLabel = isPeriodReport\n ? `For the period from ${formatDateForDisplay(startDate)} to ${formatDateForDisplay(endDate)}`\n : `As of ${formatDateForDisplay(endDate)}`;\n } else if (endDate) {\n periodLabel = 'Since Inception';\n }\n\n const rows: ExcelRow[] = [\n { cells: [] },\n { cells: [createCell(reportLabel, 'report-header')] },\n { cells: [createCell(`Generated on ${reportDateLabel}`)] },\n { cells: [createCell(periodLabel)] },\n { cells: [createCell(entitiesLabel)] },\n ...options.map(option => ({\n cells: [createCell(`${option.label}: ${option.value ? 'Yes' : 'No'}`)]\n })),\n { cells: [] }\n ];\n\n return rows;\n}\n\nfunction createCell(value: string, styleId?: string): { data: { value: string, type: 'String' }, styleId?: string } {\n return {\n data: { value, type: 'String' },\n ...(styleId && { styleId })\n };\n}\n","import {\n ILoadingOverlayComp,\n ILoadingOverlayParams,\n INoRowsOverlayComp,\n INoRowsOverlayParams,\n} from \"ag-grid-community\";\n\nimport { loadingIcon } from \"..\";\n\nexport class LoadingOverlay implements ILoadingOverlayComp {\n declare eGui: HTMLDivElement;\n\n init(_params: ILoadingOverlayParams) {\n this.eGui = document.createElement(\"div\");\n this.eGui.innerHTML = `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n }\n\n getGui() {\n return this.eGui;\n }\n}\n\nexport class NoRowsOverlay implements INoRowsOverlayComp {\n declare eGui: HTMLDivElement;\n\n init(_params: INoRowsOverlayParams) {\n this.eGui = document.createElement(\"div\");\n this.eGui.innerHTML = `\n
\n There's no data here. Select options above and click \"Run Report\" to generate a report.\n
\n `;\n }\n\n getGui() {\n return this.eGui;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport {\n GridOptions,\n createGrid,\n ColumnPinnedType,\n CellClassParams,\n GetRowIdParams,\n ToolPanelDef,\n GetContextMenuItemsParams,\n MenuItemDef,\n GridApi,\n} from \"ag-grid-enterprise\";\nimport {\n GLAccountCellRenderer,\n GLCellRenderer,\n AccountCodeCellRenderer,\n TagCellRenderer,\n} from \"../helpers/reports/renderers\";\nimport { processSavedReport, saveReportTemplate, updateSavedReportTemplate } from \"../helpers/reports/saved_reports\";\nimport {\n defaultGLExportParams,\n getClassesForAccounts,\n excelStyles,\n headerRows,\n getClassesForCells,\n} from \"../helpers/reports/excel_options\";\nimport { dataTypeDefinitions, formatDateForDisplay } from \"../helpers/reports/formatters\";\nimport { LoadingOverlay, NoRowsOverlay } from \"../helpers/reports/overlays\";\nimport { IGridOptionsValue, ReportType, ReportOption } from \"../types\";\nimport {\n validateDateSelected,\n setDateAndAlertDisplay,\n requestReportData,\n getOptionState,\n numberValueGetter,\n processReportDataResponse,\n addAutoLoadParamToUrl,\n updateBreadcrumb,\n} from \"../helpers/reports/utils\";\nimport { getCheckboxValues, setOptionsCheckboxValue, setSelectValues, getSelectValues } from \"../helpers/reports/index\";\nimport { loadDateInputs, prepareDateRangeOptions } from \"../helpers/relative_dates\";\n\n// Connects to data-controller=\"general-ledger\"\nexport default class extends Controller {\n totalCols = new Set() as Set;\n consolidatedCols = new Set() as Set;\n options = {};\n\n static targets = [\n \"form\",\n \"grid\",\n \"dateRange\",\n \"startDate\",\n \"endDate\",\n \"ledgers\",\n \"option\",\n \"account\",\n \"ledgers\",\n \"ledgerErrors\",\n \"dateErrors\",\n \"exportButton\",\n \"updateReportButton\",\n \"saveReportButton\",\n \"dateDisplay\",\n \"alertDisplay\",\n \"saveReportName\",\n \"saveReportType\",\n \"ledgerWarning\",\n ];\n\n static values = {\n gridOptions: Object,\n reportType: String,\n enableGroupSubTotals: {\n type: Boolean,\n default: true,\n },\n reportTemplateId: String,\n };\n\n // Targets\n declare gridTarget: HTMLDivElement;\n declare formTarget: HTMLFormElement;\n declare ledgersTarget: HTMLSelectElement;\n declare ledgerErrorsTarget: HTMLSpanElement;\n declare dateErrorsTarget: HTMLSpanElement;\n declare optionTargets: HTMLInputElement[];\n\n declare dateRangeTarget: HTMLSelectElement;\n declare hasDateRangeTarget: boolean;\n declare startDateTarget: HTMLInputElement;\n declare hasStartDateTarget: boolean;\n declare endDateTarget: HTMLInputElement;\n declare hasEndDateTarget: boolean;\n\n declare accountTargets: HTMLInputElement[];\n\n declare dateDisplayTarget: HTMLDivElement;\n declare alertDisplayTarget: HTMLSpanElement;\n\n declare exportButtonTarget: HTMLButtonElement;\n declare hasExportButtonTarget: boolean;\n\n declare updateReportButtonTarget: HTMLButtonElement;\n declare saveReportButtonTarget: HTMLButtonElement;\n declare hasUpdateReportButtonTarget: boolean;\n declare hasSaveReportButtonTarget: boolean;\n\n declare saveReportNameTarget: HTMLInputElement;\n declare saveReportTypeTarget: HTMLInputElement;\n\n declare ledgerWarningTarget: HTMLDivElement;\n\n // Values\n declare gridOptionsValue: IGridOptionsValue;\n declare reportTypeValue: string;\n declare hasReportTypeValue: boolean;\n declare enableGroupSubTotalsValue: boolean;\n declare reportTemplateIdValue: string;\n\n // Local variables\n declare gridApi: GridApi;\n declare gridOptions: GridOptions;\n\n declare asyncInputsLoaded: boolean;\n\n connect() {\n this.asyncInputsLoaded = false;\n this.gridTarget.classList.remove(\"loaded\");\n\n // Ensure the export button is disabled until the grid is loaded\n if (this.hasExportButtonTarget) {\n this.exportButtonTarget.disabled = true;\n }\n if (this.hasSaveReportButtonTarget) {\n this.saveReportButtonTarget.disabled = true;\n }\n\n this.gridOptions = {\n columnDefs: this.columnDefinitions(),\n headerHeight: 40,\n aggFuncs: { runningBalanceAggFunc: this.runningBalanceAggFunc },\n defaultColDef: {\n // allow every column to be aggregated\n enableValue: true,\n // allow every column to be grouped\n enableRowGroup: true,\n filter: false,\n sortable: false,\n },\n getContextMenuItems: (_params: GetContextMenuItemsParams) => {\n // Removing the export option since we have the api call to export\n const result: (string | MenuItemDef)[] = [\n \"autoSizeAll\",\n \"separator\",\n \"expandAll\",\n \"contractAll\",\n \"separator\",\n \"copy\",\n \"copyWithHeaders\",\n \"copyWithGroupHeaders\",\n ];\n\n return result;\n },\n excelStyles: excelStyles,\n suppressAggFuncInHeader: true,\n autoGroupColumnDef: {\n field: \"entity_and_account\",\n headerName: \"Entity & Account\",\n minWidth: 300,\n flex: 1,\n pinned: \"left\" as ColumnPinnedType,\n cellClass: getClassesForAccounts,\n cellRendererParams: {\n suppressCount: true,\n innerRenderer: \"GLAccountCellRenderer\",\n },\n },\n suppressMoveWhenRowDragging: true,\n rowData: null,\n // expand all groups by default\n groupDefaultExpanded: -1,\n groupTotalRow: (params) => {\n const node = params.node;\n if (node && node.level === 1) return \"bottom\";\n return undefined;\n },\n getRowId: (params: GetRowIdParams) => {\n return params.data.id.toString();\n },\n statusBar: {\n statusPanels: [\n { statusPanel: \"agTotalAndFilteredRowCountComponent\", align: \"left\" },\n { statusPanel: \"agTotalRowCountComponent\", align: \"center\" },\n { statusPanel: \"agSelectedRowCountComponent\" },\n { statusPanel: \"agAggregationComponent\" },\n ],\n },\n sideBar: {\n toolPanels: [\n {\n id: \"columns\",\n labelDefault: \"Columns\",\n labelKey: \"columns\",\n iconKey: \"columns\",\n toolPanel: \"agColumnsToolPanel\",\n toolPanelParams: {\n suppressPivots: true,\n suppressPivotMode: true,\n },\n } as ToolPanelDef,\n ],\n },\n allowContextMenuWithControlKey: true,\n dataTypeDefinitions: {\n ...dataTypeDefinitions,\n },\n getRowStyle: (params) => {\n const rowStyles = {};\n\n if (params.node.footer) {\n const isRootLevel = params.node.level === -1;\n const isAccountLevel = params.node.level === 1;\n\n if (isRootLevel) {\n return Object.assign(rowStyles, { \"background-color\": \"#CCE7EA\", \"border-top\": \"1px solid black\" });\n } else if (isAccountLevel) {\n return Object.assign(rowStyles, {\n \"background-color\": \"#e5e7eb\",\n \"border-top\": \"1px solid black\",\n \"border-bottom\": \"1px solid black\",\n });\n } else {\n return Object.assign(rowStyles, { \"border-top\": \"1px solid black\", \"border-bottom\": \"1px solid black\" });\n }\n }\n\n return rowStyles;\n },\n noRowsOverlayComponent: NoRowsOverlay,\n loadingOverlayComponent: LoadingOverlay,\n components: {\n GLAccountCellRenderer: GLAccountCellRenderer,\n },\n onRowDataUpdated: () => {\n this.gridTarget.classList.add(\"loaded\");\n },\n cellSelection: true,\n };\n\n // update additional custom options from gridOptions\n for (const option in this.gridOptionsValue) {\n // eslint-disable-next-line no-prototype-builtins\n if (!this.gridOptions.hasOwnProperty(option)) {\n continue;\n }\n\n this.gridOptions[option] = this.gridOptionsValue[option];\n }\n\n if (this.reportTemplateIdValue) {\n processSavedReport(this, this.reportTemplateIdValue);\n } else if (this.gridOptionsValue.autoLoadReport) {\n this.createGrid();\n this.loadGridData(new Event(\"autoload\"));\n } else {\n this.createGrid();\n }\n }\n\n columnDefinitions() {\n const defaultNumberColDef = {\n minWidth: 120,\n cellDataType: \"number\",\n filter: false,\n sortable: false,\n cellClass: (params: CellClassParams) => this.combineClasses(params, [\"ag-right-aligned-cell\", \"font-mono\"]),\n valueGetter: numberValueGetter,\n cellRenderer: GLCellRenderer,\n };\n\n const columnDefs = [\n {\n field: \"entity\",\n headerName: \"Entity\",\n minWidth: 200,\n rowGroup: true,\n hide: true,\n cellClass: getClassesForCells,\n },\n {\n field: \"account\",\n headerName: \"Account\",\n minWidth: 150,\n rowGroup: true,\n hide: true,\n cellClass: getClassesForCells,\n },\n {\n field: \"effectiveAt\",\n headerName: \"Effective At\",\n minWidth: 140,\n cellClass: (params: CellClassParams) => this.combineClasses(params, [\"font-mono\"]),\n cellDataType: \"dateString\",\n cellRenderer: GLCellRenderer,\n },\n {\n field: \"description\",\n headerName: \"Description\",\n minWidth: 200,\n cellClass: getClassesForCells,\n cellRenderer: GLCellRenderer,\n },\n {\n field: \"amount\",\n headerName: \"Amount\",\n minWidth: 150,\n width: 200,\n aggFunc: \"sum\",\n ...defaultNumberColDef,\n },\n {\n field: \"accountBalance\",\n headerName: \"Account Balance\",\n minWidth: 150,\n width: 200,\n valueGetter: numberValueGetter,\n aggFunc: this.runningBalanceAggFunc,\n ...defaultNumberColDef,\n },\n {\n field: \"accountCode\",\n headerName: \"Account Code\",\n minWidth: 160,\n hide: !getOptionState(this, \"show_account_codes\"),\n cellClass: getClassesForCells,\n cellRenderer: AccountCodeCellRenderer,\n cellDataType: \"text\",\n },\n {\n field: \"tags\",\n headerName: \"Tags\",\n flex: 0,\n cellEditorPopup: true,\n minWidth: 400,\n width: 500,\n hide: !getOptionState(this, \"show_tags\"),\n cellClass: getClassesForCells,\n cellRenderer: TagCellRenderer,\n cellDataType: \"text\",\n },\n ];\n\n return columnDefs;\n }\n\n combineClasses(params: CellClassParams, customClasses: string[] = []): string[] {\n const baseClasses = getClassesForCells(params);\n const baseClassesArray = Array.isArray(baseClasses) ? baseClasses : [baseClasses];\n return [...new Set([...baseClassesArray, ...customClasses])];\n }\n\n createGrid() {\n this.gridApi = createGrid(this.gridTarget, this.gridOptions);\n this.gridApi.showNoRowsOverlay();\n }\n\n // We need to set the grid state before the grid is created in order for it to work.\n // Currently there is no way to update the state after the grid had been initialized.\n // State is set using initialState: https://github.com/ag-grid/ag-grid/issues/7445\n loadAgGridState(agGridState) {\n if (agGridState) {\n this.gridOptions.initialState = agGridState;\n\n // Rely on the state to expand groups by default\n this.gridOptions.groupDefaultExpanded = 0;\n }\n }\n\n disconnect() {\n if (this.gridApi) {\n this.gridApi.destroy();\n }\n }\n\n restoreInitialGridState() {\n this.gridOptions.initialState = null;\n this.gridOptions.groupDefaultExpanded = -1; // reset to start with all rows expanded\n }\n\n async loadGridData(event: Event) {\n this.gridApi.setGridOption(\"loading\", true);\n this.gridTarget.classList.remove(\"loaded\");\n\n addAutoLoadParamToUrl();\n\n if (!this.optionTargets.includes(event.currentTarget as HTMLInputElement)) {\n event.preventDefault();\n }\n\n this.totalCols.clear();\n\n const sessionReportOptions = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n if (event.type == \"autoload\" && sessionReportOptions) {\n this.loadValuesToInputs(sessionReportOptions);\n }\n\n if (!validateDateSelected(this)) {\n return;\n }\n\n // Show warning if all ledgers are selected\n this.checkAndShowLedgerWarning();\n\n // we do this for accounts here because they are loaded asynchronously\n // and might not be available at the time of the run. Then we use the turbo:frame-render event on _account_options_slideover partial to call loadAsyncInputs()\n let accountTemplateIds = [];\n if (this.asyncInputsLoaded) {\n accountTemplateIds = getCheckboxValues(this.accountTargets);\n } else {\n accountTemplateIds = sessionReportOptions?.account_code_ids;\n }\n\n const body = {\n start_date: this.hasStartDateTarget ? this.startDateTarget.value : null,\n end_date: this.hasEndDateTarget ? this.endDateTarget.value : null,\n date_range: this.hasDateRangeTarget ? this.dateRangeTarget.value : null,\n ledger_ids: getSelectValues(this.ledgersTarget),\n account_template_ids: accountTemplateIds,\n ...this.getOptionsObject(),\n };\n\n if (event.type == \"click\") {\n sessionStorage.setItem(this.sessionStorageKey(\"report_options\"), JSON.stringify(body));\n }\n\n const response = await requestReportData(body);\n processReportDataResponse(this, response, (data) => {\n this.renderGrid(data);\n });\n }\n\n updateBreadcrumb(event: Event) {\n const element = event.srcElement as HTMLElement;\n\n updateBreadcrumb(this.reportTemplateIdValue, element);\n }\n\n renderGrid(data) {\n this.setColumnDefinitionsAndRowData(data);\n\n this.gridApi.setGridOption(\"loading\", false);\n }\n\n loadValuesToInputs(values) {\n loadDateInputs(values, this);\n\n const dateValue = values.date_range;\n if (dateValue === \"since_inception\") {\n this.startDateTarget.disabled = true;\n } else {\n this.startDateTarget.disabled = false;\n }\n\n setSelectValues(this.ledgersTarget, values.ledger_ids.map(Number));\n\n setOptionsCheckboxValue(this.optionTargets, \"show_no_activity_accounts\", values.show_no_activity_accounts);\n setOptionsCheckboxValue(this.optionTargets, \"show_tags\", values.show_tags);\n setOptionsCheckboxValue(this.optionTargets, \"show_account_codes\", values.show_account_codes);\n }\n\n loadAsyncInputs() {\n const sessionReportOptions = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n\n if (sessionReportOptions && sessionReportOptions.account_template_ids) {\n this.clearCheckboxValues(this.accountTargets);\n this.setCheckboxValues(this.accountTargets, sessionReportOptions.account_template_ids.map(Number));\n }\n\n this.asyncInputsLoaded = true;\n this.dispatch(\"report-inputs-loaded\");\n }\n\n clearCheckboxValues(checkboxes: HTMLInputElement[]) {\n checkboxes.forEach((checkbox) => {\n checkbox.checked = false;\n checkbox.indeterminate = false;\n checkbox.dispatchEvent(new Event(\"change\"));\n const customEvent = new CustomEvent(\"checkbox-updated\", { bubbles: true, detail: { checkbox } });\n checkbox.dispatchEvent(customEvent);\n });\n }\n\n // Custom setCheckboxValues function to handle the custom event\n setCheckboxValues(checkboxes: HTMLInputElement[], selectedCheckboxes: number[]) {\n checkboxes.forEach((checkbox) => {\n if (selectedCheckboxes.includes(parseInt(checkbox.value))) {\n checkbox.checked = true;\n checkbox.dispatchEvent(new Event(\"change\"));\n const customEvent = new CustomEvent(\"checkbox-updated\", { bubbles: true, detail: { checkbox } });\n checkbox.dispatchEvent(customEvent);\n }\n });\n }\n\n exportReport(event: Event) {\n event.preventDefault();\n\n const reportType: ReportType = this.hasReportTypeValue ? (this.reportTypeValue as ReportType) : \"sumit-report\";\n const reportDate = new Date();\n\n const fileName = `${reportType}-${reportDate.toISOString().replace(/:/g, \"-\")}.xlsx`;\n\n const { showNoActivityAccountsValue } = this.getTogglesValues();\n const regularOptions: ReportOption[] = [\n { label: \"Showing accounts w/ no activity\", value: showNoActivityAccountsValue },\n ];\n\n // Used to remove the first line between the headers and first set of entries\n let hasSkippedFirstLevel1Row = false;\n let hasSeenFirstLevel1Row = false;\n\n this.gridApi.exportDataAsExcel({\n prependContent: headerRows(\n reportType,\n reportDate,\n this.startDateTarget.value,\n this.endDateTarget.value,\n this.getSelectedLedgerNames(),\n regularOptions,\n ),\n fileName,\n author: \"SumIt Software, Inc.\",\n sheetName: reportType,\n rowGroupExpandState: \"match\",\n headerRowHeight: 30,\n shouldRowBeSkipped: function (params) {\n // If row is skipped it doesn't get processed by the processCellCallback()\n if (params.node.level === 1) {\n if (params.node.expanded && !hasSkippedFirstLevel1Row && !hasSeenFirstLevel1Row) {\n hasSeenFirstLevel1Row = true;\n hasSkippedFirstLevel1Row = true;\n return true;\n } else {\n hasSeenFirstLevel1Row = false;\n return false;\n }\n } else {\n return !params.node.displayed || params.node.level === 0;\n }\n },\n columnKeys: this.getColumnKeysForExport(this.gridApi),\n ...defaultGLExportParams,\n });\n }\n\n getColumnKeysForExport(gridApi: GridApi): string[] {\n const columnKeys = [\"entity\", \"account\"];\n\n gridApi.getAllGridColumns().forEach((column) => {\n const colDef = column.getColDef();\n const field = colDef.field;\n\n if (column.isVisible() && field !== \"entity_and_account\") {\n if (!columnKeys.includes(field)) {\n columnKeys.push(field);\n }\n }\n });\n\n return columnKeys;\n }\n\n getReportOptions() {\n const options = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n options[\"ag_grid_state\"] = this.gridApi.getState();\n\n return options;\n }\n\n async saveReportTemplate(e: Event) {\n e.preventDefault();\n\n const reportTemplateData = {\n report_type: this.saveReportTypeTarget.value,\n report_options: prepareDateRangeOptions(this.getReportOptions()),\n };\n\n await saveReportTemplate(reportTemplateData, this.saveReportTypeTarget.value, this.saveReportNameTarget.value);\n }\n\n updateSavedReportTemplate() {\n const reportTemplateData = {\n report_type: this.saveReportTypeTarget.value,\n report_options: prepareDateRangeOptions(this.getReportOptions()),\n };\n\n updateSavedReportTemplate(reportTemplateData, this.reportTemplateIdValue);\n }\n\n getOptionsObject() {\n const options = {};\n this.optionTargets.forEach((option) => {\n options[option.name] = option.checked;\n });\n return options;\n }\n\n setColumnDefinitionsAndRowData(data) {\n setDateAndAlertDisplay(this, data);\n\n this.gridApi.updateGridOptions({\n columnDefs: this.columnDefinitions(),\n });\n this.gridApi.setGridOption(\"rowData\", data.row_data);\n\n if (!this.gridOptions.initialState) {\n this.autoSizeColumns();\n }\n\n if (this.hasExportButtonTarget) {\n this.exportButtonTarget.disabled = false;\n }\n if (this.hasSaveReportButtonTarget) {\n this.saveReportButtonTarget.disabled = false;\n }\n if (this.hasUpdateReportButtonTarget && this.reportTemplateIdValue) {\n this.updateReportButtonTarget.classList.remove(\"hidden\");\n } else {\n this.updateReportButtonTarget.classList.add(\"hidden\");\n }\n }\n\n reportDateHeader() {\n return `For the period ${formatDateForDisplay(this.startDateTarget.value)} - ${formatDateForDisplay(\n this.endDateTarget.value,\n )}`;\n }\n\n toggleTagsColumn() {\n const showTags = getOptionState(this, \"show_tags\");\n this.gridApi.setColumnsVisible([\"tags\"], showTags);\n setDateAndAlertDisplay(this, {});\n }\n\n toggleAccountCodesColumn() {\n const showAccountCodes = getOptionState(this, \"show_account_codes\");\n this.gridApi.setColumnsVisible([\"accountCode\"], showAccountCodes);\n setDateAndAlertDisplay(this, {});\n }\n\n runningBalanceAggFunc(values) {\n // Return the last value in the group\n return values.values.length > 0 ? values.values[values.values.length - 1] : 0;\n }\n\n autoSizeColumns() {\n this.gridApi.sizeColumnsToFit();\n }\n\n getTogglesValues() {\n const showNoActivityAccountsCheckbox = document.querySelector(\"#show_no_activity_accounts\") as HTMLInputElement;\n const showNoActivityAccountsValue = showNoActivityAccountsCheckbox?.checked;\n\n return { showNoActivityAccountsValue };\n }\n\n getSelectedLedgerNames() {\n return getSelectValues(this.ledgersTarget).map(\n (id) => (this.ledgersTarget.querySelector(`option[value=\"${id}\"]`) as HTMLOptionElement).innerText,\n );\n }\n\n sessionStorageKey(key: string) {\n return `general_ledger_${key}`;\n }\n\n checkAndShowLedgerWarning(): boolean {\n const ledgerSelect = this.ledgersTarget as HTMLSelectElement;\n const selectedOptions = Array.from(ledgerSelect.selectedOptions);\n const allLedgerCount = ledgerSelect.options.length - 1; // Subtract 1 for the placeholder option\n\n const allLedgersSelected = selectedOptions.length === 0 || selectedOptions.length === allLedgerCount;\n\n if (allLedgersSelected) {\n this.ledgerWarningTarget.classList.remove(\"hidden\");\n } else {\n this.ledgerWarningTarget.classList.add(\"hidden\");\n }\n\n return allLedgersSelected;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n\n// Connects to data-controller=\"ignore-transaction\"\nexport default class extends Controller {\n static targets = [\"checkbox\", \"selectors\", \"applyToExisting\"];\n\n declare checkboxTarget: HTMLInputElement;\n declare selectorsTarget: HTMLElement;\n declare applyToExistingTarget: HTMLElement;\n\n declare hasApplyToExistingTarget: boolean;\n\n connect() {\n this.update();\n }\n\n update() {\n this.selectorsTarget.classList.toggle(\"hidden\", this.checkboxTarget.checked);\n\n if (this.hasApplyToExistingTarget) {\n this.applyToExistingTarget.classList.toggle(\"hidden\", !this.checkboxTarget.checked);\n }\n }\n\n}","import { Controller } from \"@hotwired/stimulus\";\nimport { formatCurrencyValue } from \"../helpers/currency_formatter\";\n\n// Connects to data-controller=\"input-currency-formatter\"\nexport default class extends Controller {\n static values = {\n skipEnterKeyAsTab: Boolean,\n strictValidation: {\n type: Boolean,\n default: false,\n },\n };\n\n declare skipEnterKeyAsTabValue: boolean;\n declare strictValidationValue: boolean;\n declare originalValue: string;\n private lastValidValue: string = \"\";\n\n connect() {\n this.originalValue = this.element.value;\n\n this.formatInput();\n }\n\n formatInput() {\n const inputValue = this.element.value;\n\n try {\n const formattedValue = formatCurrencyValue(inputValue, {\n throwOnInvalid: this.strictValidationValue,\n });\n\n if (formattedValue !== inputValue) {\n this.element.value = formattedValue;\n }\n this.lastValidValue = formattedValue;\n } catch (error) {\n console.error(error);\n\n // If strict validation is on and value is invalid, restore last valid value\n if (this.strictValidationValue) {\n this.element.value = this.lastValidValue;\n }\n }\n }\n\n highlight() {\n this.element.select();\n }\n\n handleEnterKeyAsTab(event) {\n if (this.skipEnterKeyAsTabValue) return;\n\n event.preventDefault();\n this.focusOnNextInput(event.currentTarget);\n }\n\n focusOnNextInput(currentTarget) {\n if (this.skipEnterKeyAsTabValue) return;\n\n const inputs = document.querySelectorAll(\"input, textarea\");\n const currentIndex = Array.from(inputs).indexOf(currentTarget);\n if (inputs[currentIndex]) {\n (inputs[currentIndex + 1] as HTMLElement).focus();\n }\n }\n}\n","import { IOneSchemaOverridesResponseData } from \"../../types\";\n\nexport const processSchemaOverridesResponse = (responseData: IOneSchemaOverridesResponseData) => {\n const { template_overrides } = responseData;\n const { accounts, entities, tags, account_codes } = template_overrides;\n\n const accountOverrides = accounts.map((account) => {\n return {\n value: account.number_and_name,\n color: \"#028698\",\n alternative_names: [account.number.toString(), account.name, account.number_and_name],\n prefix_id: account.prefix_id,\n };\n });\n\n const entityOverrides = entities.map((entity) => {\n return { value: entity.name, color: \"#595959\", prefix_id: entity.prefix_id };\n });\n\n const tagOverrides = tags.map((tag) => {\n return {\n value: tag.full_name,\n color: tag.color_bg,\n alternative_names: [tag.name, ` ${tag.name}`, `${tag.name} `, ` ${tag.name} `, tag.full_name],\n prefix_id: tag.prefix_id,\n };\n });\n\n const accountCodeOverrides = account_codes.map((accountCode) => {\n return {\n value: accountCode.full_name,\n color: \"#2F7AEB\",\n alternative_names: [accountCode.name, accountCode.full_name],\n prefix_id: accountCode.prefix_id,\n };\n });\n\n return {\n accountOverrides: accountOverrides,\n entityOverrides: entityOverrides,\n tagOverrides: tagOverrides,\n accountCodeOverrides: accountCodeOverrides,\n };\n};\n","import { Controller } from \"@hotwired/stimulus\";\nimport oneschemaImporter, { OneSchemaImporterClass } from \"@oneschema/importer\";\nimport { post, get } from \"@rails/request.js\";\nimport { Turbo, FrameElement } from \"@hotwired/turbo-rails\";\nimport { IOneSchemaOverridesResponseData, IOneSchemaPicklistOption } from \"../types\";\nimport { processSchemaOverridesResponse } from \"../helpers/one_schema\";\n\n// Connects to data-controller=\"journal-entry-importer\"\nexport default class extends Controller {\n declare importer: OneSchemaImporterClass | undefined;\n\n static targets = [\"importButton\"];\n\n static values = {\n jwtToken: String,\n overridesUrl: String,\n importUrl: String,\n clientId: String,\n sessionToken: {\n type: String,\n default: \"\",\n },\n devMode: {\n type: Boolean,\n default: false,\n },\n };\n\n declare hasJwtTokenValue: boolean;\n declare jwtTokenValue: string;\n\n declare sessionTokenValue: string;\n\n declare clientIdValue: string;\n declare overridesUrlValue: string;\n declare importUrlValue: string;\n declare devModeValue: boolean;\n\n declare importButtonTarget: HTMLButtonElement;\n\n declare accountOverrides: IOneSchemaPicklistOption[];\n declare entityOverrides: IOneSchemaPicklistOption[];\n declare tagOverrides: IOneSchemaPicklistOption[];\n declare accountCodeOverrides: IOneSchemaPicklistOption[];\n\n connect(): void {\n this.updateButtonStyling();\n }\n\n async launchImporter(_event: Event): Promise {\n this.showLoader();\n\n const schemaOverrides = await get(this.overridesUrlValue, { responseKind: \"json\" });\n\n if (!this.importer) {\n this.initializeImporter();\n }\n\n if (schemaOverrides.ok) {\n this.processOverrides(await schemaOverrides.json);\n } else {\n console.warn(\"error fetching overrides\");\n }\n\n this.importer.launch({\n userJwt: this.userJwt,\n templateKey: \"journal_entry_upload\",\n sessionToken: this.sessionTokenValue,\n templateOverrides: {\n columns_to_update: [\n {\n key: \"ledger_name\",\n validation_options: { picklist_options: this.entityOverrides },\n },\n {\n key: \"account_name\",\n validation_options: { picklist_options: this.accountOverrides },\n },\n {\n key: \"tags\",\n validation_options: { picklist_options: this.tagOverrides },\n },\n {\n key: \"account_code\",\n validation_options: { picklist_options: this.accountCodeOverrides },\n },\n ],\n },\n });\n }\n\n initializeImporter(): void {\n this.importer = oneschemaImporter({\n clientId: this.clientIdValue,\n templateKey: \"journal_entry_upload\",\n importConfig: { type: \"local\" },\n devMode: this.devModeValue,\n className: \"oneschema-importer\",\n styles: {\n position: \"fixed\",\n top: \"0\",\n left: \"0\",\n width: \"100vw\",\n height: \"100vh\",\n zIndex: \"1000\",\n },\n });\n\n this.importer.on(\"launched\", (data: { sessionToken: string }) => {\n this.hideLoader();\n\n this.sessionTokenValue = data.sessionToken;\n\n this.updateButtonStyling();\n });\n\n this.importer.on(\"success\", async (data) => {\n this.showLoader();\n\n const response = await post(this.importUrlValue, {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({ one_schema: { session_token: this.sessionTokenValue, ...data } }),\n });\n\n Turbo.renderStreamMessage(await response.text);\n\n if (!response.ok) {\n console.error(\"There was an error importing the file.\");\n }\n\n this.hideLoader();\n });\n\n this.importer.on(\"cancel\", () => {\n console.warn(\"Import cancelled\");\n\n this.sessionTokenValue = \"\";\n\n this.updateButtonStyling();\n });\n\n this.importer.on(\"error\", (error) => {\n console.error(error);\n });\n }\n\n disconnect(): void {\n this.importer?.close(true);\n }\n\n showLoader() {\n this.importButtonTarget.disabled = true;\n this.importButtonTarget.querySelector(\"div#processing_spinner\").classList.remove(\"hidden\");\n this.formTurboFrame.classList.add(...this.formOverlayClasses);\n }\n\n hideLoader() {\n this.importButtonTarget.querySelector(\"div#processing_spinner\").classList.add(\"hidden\");\n this.importButtonTarget.disabled = false;\n this.formTurboFrame.classList.remove(...this.formOverlayClasses);\n }\n\n processOverrides(responseData: IOneSchemaOverridesResponseData): void {\n const processedData = processSchemaOverridesResponse(responseData);\n\n this.accountOverrides = processedData.accountOverrides;\n this.entityOverrides = processedData.entityOverrides;\n this.tagOverrides = processedData.tagOverrides;\n this.accountCodeOverrides = processedData.accountCodeOverrides;\n }\n\n updateButtonStyling(): void {\n if (this.sessionTokenValue !== \"\") {\n this.importButtonTarget.classList.add(\"btn-tertiary\");\n this.importButtonTarget.classList.remove(\"btn-secondary\");\n this.importButtonTarget.querySelector(\"span#button_copy\").textContent = \"Review File\";\n } else {\n this.importButtonTarget.classList.remove(\"btn-tertiary\");\n this.importButtonTarget.classList.add(\"btn-secondary\");\n this.importButtonTarget.querySelector(\"span#button_copy\").textContent = \"Upload File\";\n }\n }\n\n get userJwt(): string {\n return this.hasJwtTokenValue ? this.jwtTokenValue : \"unknown\";\n }\n\n get formOverlayClasses(): string[] {\n return [\"pointer-events-none\", \"transition-opacity\", \"duration-150\", \"ease-in-out\", \"opacity-50\"];\n }\n\n get formTurboFrame(): FrameElement {\n return document.querySelector(\"turbo-frame#form\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"ledger-entries\"\nexport default class extends Controller {\n static targets = [\"debitsTotal\", \"creditsTotal\", \"row\", \"accountSelect\", \"accountCodeSelect\", \"deleteRowButton\"];\n\n declare accountSelectTargets: HTMLInputElement[];\n declare accountCodeSelectTargets: HTMLInputElement[];\n\n declare debitsTotalTarget: HTMLElement;\n declare hasDebitsTotalTarget: boolean;\n\n declare creditsTotalTarget: HTMLElement;\n declare hasCreditsTotalTarget: boolean;\n\n declare rowTargets: HTMLSpanElement[];\n declare deleteRowButtonTargets: HTMLButtonElement[];\n\n connect() {\n }\n\n rowTargetConnected(_element: HTMLDivElement) {\n this.handleUpdates();\n }\n\n rowTargetDisconnected(_element: HTMLDivElement) {\n this.handleUpdates();\n }\n\n handleUpdates(event?: Event) {\n const targetInput: HTMLInputElement = event?.currentTarget as HTMLInputElement;\n\n let rowNumber = 1;\n let creditsTotal = 0;\n let debitsTotal = 0;\n\n // Iterate through all the row elements and update the row number for each row, and keep track\n // of the total credits and debits.\n this.rowTargets.forEach((row: HTMLDivElement) => {\n // If the row contains an element marked for removal, we don't want to include it in the total.\n if (row.querySelector(\"input[name*='_destroy'][value='1']\")) {\n return;\n }\n\n const counter = row.querySelector(\".counter\") as HTMLSpanElement;\n counter.innerText = (rowNumber++).toString();\n\n this.clearContraInput(targetInput, row);\n\n creditsTotal += this.extractNumber(row, \"credits\");\n debitsTotal += this.extractNumber(row, \"debits\");\n });\n\n if (this.hasCreditsTotalTarget) {\n this.setTotal(this.creditsTotalTarget, creditsTotal);\n }\n\n if (this.hasDebitsTotalTarget) {\n this.setTotal(this.debitsTotalTarget, debitsTotal);\n }\n }\n\n clearContraInput(targetInput: HTMLInputElement, row: HTMLDivElement) {\n if (targetInput) {\n const isCreditUpdate = targetInput.name.includes(\"credits\")\n\n const rowDebitInput = this.getInputByName(row, \"debits\")\n const rowCreditInput = this.getInputByName(row, \"credits\")\n\n if (isCreditUpdate && rowCreditInput.id === targetInput.id && this.extractNumber(row, \"credits\") !== 0) {\n rowDebitInput.value = \"$0.00\";\n } else if(!isCreditUpdate && rowDebitInput.id === targetInput.id && this.extractNumber(row, \"debits\") !== 0) {\n rowCreditInput.value = \"$0.00\";\n }\n }\n }\n\n setTotal(target: HTMLElement, total: number) {\n target.innerText = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }).format(total);\n }\n\n extractNumber(row: HTMLDivElement, name: string): number {\n const input = this.getInputByName(row, name);\n\n if (input) {\n const numericValue = input.value.replace(/^0+|[^0-9.]/g, '');\n const value = parseFloat(numericValue);\n\n if (!isNaN(value)) {\n return value;\n }\n }\n\n return 0;\n }\n\n getInputByName(row: HTMLDivElement, name: string): HTMLInputElement {\n return row.querySelector(`input[name*='${name}']`) as HTMLInputElement;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"ledger-name\"\nexport default class extends Controller {\n static targets = [\"ledgerSelect\", \"title\"];\n\n declare ledgerSelectTarget: HTMLSelectElement;\n declare titleTarget: HTMLElement;\n\n connect() {\n this.updateName();\n }\n\n handleLedgerChange(_event) {\n this.updateName();\n }\n\n updateName() {\n this.titleTarget.textContent = this.ledgerSelectTarget.selectedOptions[0].text;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport TomSelect from \"tom-select\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\n// Connects to data-controller=\"ledger-select\"\nexport default class extends Controller {\n declare select: TomSelect;\n\n static values = {\n ledgerOptions: Array,\n controlClasses: Array,\n maxItems: Number,\n };\n\n declare controlClassesValue: string[];\n declare maxItemsValue: number;\n declare hasMaxItemsValue: boolean;\n\n connect() {\n const controlClasses = [\"ts-control\", ...this.controlClassesValue].join(\" \");\n let plugins = [];\n\n if (this.element.multiple) {\n plugins = [\"remove_button\"];\n }\n\n let maxItems = null;\n if (this.hasMaxItemsValue) {\n maxItems = this.maxItemsValue;\n }\n\n this.select = new TomSelect(this.element as TomInput, {\n hidePlaceholder: true,\n controlClass: controlClasses,\n plugins: plugins,\n maxItems: this.element.multiple ? maxItems : 1,\n render: {\n option: (data, escape) => {\n if (data.disabled || String(data.disabledLabel).toLowerCase() === \"true\") {\n return `\n
\n ${escape(data.text)}\n Deactivated\n
\n `;\n } else {\n return `\n
\n ${escape(data.text)}\n
\n `;\n }\n },\n },\n });\n }\n\n disconnect() {\n this.select.destroy();\n }\n\n reconnect() {\n this.disconnect();\n this.connect();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"ledger-transaction\"\nexport default class extends Controller {\n static targets = [\"transactionContainer\"];\n\n declare transactionContainerTarget: HTMLElement;\n\n handleToggle(_event) {\n if (this.transactionContainerTarget.dataset.toggleOpenValue === \"true\") {\n this.handleShow(_event);\n } else {\n this.handleHide(_event);\n }\n }\n\n handleShow(_event) {\n const toRemove = [\"border-l\", \"border-r\"];\n const toAdd = [\"bg-[#F1FBFC]\", \"border\", \"border-cyan-600\"];\n\n this.removeClasses(toRemove);\n this.addClasses(toAdd);\n }\n\n handleHide(_event) {\n const toRemove = [\"bg-[#F1FBFC]\", \"border\", \"border-cyan-600\"];\n const toAdd = [\"border-l\", \"border-r\"];\n\n this.removeClasses(toRemove);\n this.addClasses(toAdd);\n }\n\n addClasses(classes) {\n for (const className of classes) {\n this.transactionContainerTarget.classList.add(className);\n }\n }\n\n removeClasses(classes) {\n for (const className of classes) {\n this.transactionContainerTarget.classList.remove(className);\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\n\n// Connects to data-controller=\"ledger-transaction-notices\"\nexport default class extends Controller {\n static targets = [\"ledgerSelect\", \"effectiveAt\", \"effectiveAtWas\", \"alert\", \"cashAccountNotice\"];\n\n static values = {\n noticesUrl: String,\n ledgerLastClosedAtDates: Object,\n };\n\n declare noticesUrlValue: string;\n\n declare ledgerSelectTargets: HTMLSelectElement[];\n declare effectiveAtTarget: HTMLInputElement;\n declare effectiveAtWasTarget: HTMLInputElement;\n declare alertTarget: HTMLDivElement;\n\n declare cashAccountNoticeTarget: HTMLDivElement;\n declare hasCashAccountNoticeTarget: boolean;\n\n declare ledgerLastClosedAtDatesValue: object;\n\n connect() {\n this.cashAccountNotice();\n }\n\n effectiveAtTargetConnected() {\n this.effectiveAtNotice();\n }\n\n getAllAccountSelects() {\n return this.element.querySelectorAll(\"[data-account-select-container] select\");\n }\n\n handleAccountChange() {\n this.cashAccountNotice();\n }\n\n handleEffectiveAtChange() {\n this.effectiveAtNotice();\n }\n\n handleLedgerChange() {\n this.effectiveAtNotice();\n }\n\n cashAccountNotice() {\n const accountIds = [];\n const selectElements = this.getAllAccountSelects();\n\n selectElements.forEach((selectTarget: HTMLSelectElement) => {\n if (selectTarget.hasChildNodes()) {\n const selectedAccountId = selectTarget.selectedOptions[0].value;\n\n if (selectedAccountId !== \"\") {\n accountIds.push(selectedAccountId);\n }\n }\n });\n\n if (accountIds.length === 0) {\n if (this.hasCashAccountNoticeTarget) {\n this.cashAccountNoticeTarget.innerHTML = \"\";\n }\n return;\n }\n\n const url = new URL(this.noticesUrlValue, window.location.href);\n\n post(url.toString(), {\n body: {\n account_ids: accountIds,\n notices_to_render: [this.cashAccountNoticeTarget.id],\n },\n responseKind: \"turbo-stream\",\n });\n }\n\n effectiveAtNotice() {\n const effectiveDate = new Date(this.effectiveAtTarget.value);\n const effectiveDateWas = this.effectiveAtWasTarget.value ? new Date(this.effectiveAtWasTarget.value) : null;\n\n if (!effectiveDate) return;\n\n let hasClosedEntry = false;\n\n this.ledgerSelectTargets.forEach((select) => {\n const closeDateString = this.ledgerLastClosedAtDatesValue[select.value];\n if (!closeDateString) {\n return;\n }\n\n const closeDate = new Date(closeDateString);\n\n const fromNullToOutsideClosedPeriod = !effectiveDateWas && effectiveDate > closeDate;\n const fromOutsideToOutsideClosedPeriod =\n effectiveDateWas && effectiveDateWas > closeDate && effectiveDate > closeDate;\n if (!fromNullToOutsideClosedPeriod && !fromOutsideToOutsideClosedPeriod) {\n hasClosedEntry = true;\n }\n });\n\n if (hasClosedEntry) {\n this.alertTarget.classList.remove(\"hidden\");\n\n const input = this.alertTarget.querySelector(\"input\");\n if (input) {\n input.disabled = false;\n }\n } else {\n this.alertTarget.classList.add(\"hidden\");\n\n // Disabling the input prevents it from being submitted with the form\n const input = this.alertTarget.querySelector(\"input\");\n if (input) {\n input.disabled = true;\n }\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport oneschemaImporter, { OneSchemaImporterClass } from \"@oneschema/importer\";\nimport { post, get } from \"@rails/request.js\";\nimport { IOneSchemaOverridesResponseData, IOneSchemaPicklistOption } from \"../types\";\nimport { processSchemaOverridesResponse } from \"../helpers/one_schema\";\nimport { Turbo } from \"@hotwired/turbo-rails\";\n\ninterface IOneSchemaImportedRecord {\n rank: number;\n addepar_field: string;\n addepar_value: string;\n sumit_record: string;\n prefix_id?: string;\n}\n\n// Connects to data-controller=\"mapping-manager-importer\"\nexport default class extends Controller {\n declare importer: OneSchemaImporterClass | undefined;\n declare picklistOptions: IOneSchemaPicklistOption[];\n\n static targets = [\"importButton\"];\n\n static values = {\n jwtToken: String,\n overridesUrl: String,\n importUrl: String,\n clientId: String,\n sessionToken: {\n type: String,\n default: \"\",\n },\n devMode: {\n type: Boolean,\n default: false,\n },\n };\n\n declare hasJwtTokenValue: boolean;\n declare jwtTokenValue: string;\n\n declare overridesUrlValue: string;\n declare importUrlValue: string;\n declare clientIdValue: string;\n declare sessionTokenValue: string;\n declare devModeValue: boolean;\n\n declare importButtonTarget: HTMLButtonElement;\n\n connect(): void {}\n\n async launchImporter(_event: Event): Promise {\n this.showLoader();\n\n const schemaOverrides = await get(this.overridesUrlValue, { responseKind: \"json\" });\n\n if (!this.importer) {\n this.initializeImporter();\n }\n\n if (schemaOverrides.ok) {\n this.picklistOptions = this.processOverrides(await schemaOverrides.json);\n } else {\n console.warn(\"error fetching overrides\");\n }\n\n this.importer.launch({\n userJwt: this.userJwt,\n templateKey: \"addepar_mapping_manager\",\n sessionToken: this.sessionTokenValue,\n templateOverrides: {\n columns_to_update: [\n {\n key: \"sumit_record\",\n validation_options: { picklist_options: this.picklistOptions },\n },\n ],\n },\n });\n }\n\n initializeImporter(): void {\n this.importer = oneschemaImporter({\n clientId: this.clientIdValue,\n templateKey: \"addepar_mapping_manager\",\n importConfig: { type: \"local\" },\n devMode: this.devModeValue,\n className: \"oneschema-importer\",\n styles: {\n position: \"fixed\",\n top: \"0\",\n left: \"0\",\n width: \"100vw\",\n height: \"100vh\",\n zIndex: \"1000\",\n },\n });\n\n this.importer.on(\"launched\", (data: { sessionToken: string }) => {\n this.hideLoader();\n\n this.sessionTokenValue = data.sessionToken;\n });\n\n this.importer.on(\"success\", async (data) => {\n this.showLoader();\n\n data.records = this.postProcessImportedRecords(data.records);\n\n const response = await post(this.importUrlValue, {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({ one_schema: { session_token: this.sessionTokenValue, ...data } }),\n });\n\n Turbo.renderStreamMessage(await response.text);\n\n if (!response.ok) {\n console.error(\"There was an error importing the file.\");\n }\n\n this.hideLoader();\n });\n\n this.importer.on(\"cancel\", () => {\n console.warn(\"Import cancelled\");\n\n this.sessionTokenValue = \"\";\n });\n\n this.importer.on(\"error\", (error) => {\n console.error(error);\n });\n }\n\n processOverrides(overrides: IOneSchemaOverridesResponseData): IOneSchemaPicklistOption[] {\n const processedData = processSchemaOverridesResponse(overrides);\n\n const picklistOptions = [];\n\n processedData.accountOverrides.forEach((account) => {\n picklistOptions.push({\n ...account,\n value: `Account: ${account.value}`,\n });\n });\n\n processedData.tagOverrides.forEach((tag) => {\n picklistOptions.push({\n ...tag,\n value: `Tag: ${tag.value}`,\n });\n });\n\n processedData.accountCodeOverrides.forEach((accountCode) => {\n picklistOptions.push({\n ...accountCode,\n value: `Account Code: ${accountCode.value}`,\n });\n });\n\n return picklistOptions;\n }\n\n disconnect(): void {\n this.importer?.close(true);\n }\n\n showLoader() {\n this.importButtonTarget.disabled = true;\n this.importButtonTarget.querySelector(\"div#processing_spinner\").classList.remove(\"hidden\");\n this.importButtonTarget.querySelector(\"div#tray_icon\").classList.add(\"hidden\");\n }\n\n hideLoader() {\n this.importButtonTarget.querySelector(\"div#processing_spinner\").classList.add(\"hidden\");\n this.importButtonTarget.querySelector(\"div#tray_icon\").classList.remove(\"hidden\");\n this.importButtonTarget.disabled = false;\n }\n\n postProcessImportedRecords(records: IOneSchemaImportedRecord[]): IOneSchemaImportedRecord[] {\n return records.map((record) => {\n const prefixId = this.picklistOptions.find((option) => option.value === record.sumit_record)?.prefix_id;\n\n return {\n ...record,\n prefix_id: prefixId,\n };\n });\n }\n\n get userJwt(): string {\n return this.hasJwtTokenValue ? this.jwtTokenValue : \"unknown\";\n }\n}\n","import NestedForm from \"stimulus-rails-nested-form\";\n\n// Connects to data-controller=\"nested-addepar-transaction-filter\"\n// Borrowed from https://github.com/stimulus-components/stimulus-rails-nested-form/blob/master/src/index.ts\nexport default class extends NestedForm {\n static targets = [\"target\", \"template\", \"id\", \"row\", \"updateContainer\"];\n\n declare templateTarget: HTMLTemplateElement;\n declare targetTarget: HTMLElement;\n declare rowTargets: HTMLElement[];\n declare updateContainerTargets: HTMLElement[];\n\n connect() {\n super.connect();\n this.applyClasses();\n }\n\n add(e: Event) {\n e.preventDefault();\n\n const clone = document.importNode(this.templateTarget.content, true) as DocumentFragment;\n const elementClone = clone.firstElementChild as HTMLElement | null;\n\n if (elementClone) {\n // Replace the NEW_RECORD placeholder with a unique number for rails to use to determine if the\n // record exists or not (it shouldn't)\n const content = elementClone.innerHTML.replace(/NEW_RECORD/g, new Date().getTime().toString());\n\n elementClone.innerHTML = content;\n\n this.targetTarget.insertAdjacentElement(\"beforebegin\", elementClone);\n\n this.applyClasses();\n }\n }\n\n applyClasses() {\n this.updateContainerTargets.forEach((el, i) => {\n el.id = `addepar-transaction-filter-update-container-${i}`;\n });\n\n const nonDeletedRows = this.rowTargets.filter(row => (\n (row.querySelector(\"input[type='hidden'][name*='_destroy']\") as HTMLInputElement)?.value !== '1') && row.childElementCount !== 0\n );\n\n if (nonDeletedRows.length === 1) {\n nonDeletedRows[0].querySelector(\"button\")?.setAttribute(\"disabled\", \"disabled\");\n } else {\n nonDeletedRows[0].querySelector(\"button\")?.removeAttribute(\"disabled\");\n }\n }\n\n remove(e: Event): void {\n super.remove(e);\n this.applyClasses();\n }\n}\n","import NestedForm from \"stimulus-rails-nested-form\";\n\n// Leaving this here in case we need to mess with the functionality\n// https://www.stimulus-components.com/docs/stimulus-rails-nested-form\nexport default class extends NestedForm {\n static targets = [\"ledgerTransactionDescription\", \"ledgerEntryDescription\"];\n\n declare ledgerTransactionDescriptionTarget: HTMLTextAreaElement;\n declare ledgerEntryDescriptionTargets: HTMLTextAreaElement[];\n\n connect() {\n super.connect();\n }\n\n copyDescription() {\n this.ledgerEntryDescriptionTargets.forEach((el) => {\n el.value = this.ledgerTransactionDescriptionTarget.value;\n });\n }\n}\n","import NestedForm from \"stimulus-rails-nested-form\";\n\n// Connects to data-controller=\"nested-ledger-entry\"\n// Borrowed from https://github.com/stimulus-components/stimulus-rails-nested-form/blob/master/src/index.ts\nexport default class extends NestedForm {\n static targets = [\"target\", \"template\", \"id\", \"ledgerEntryRow\", \"ledgerTransactionDescription\", \"ledgerEntryDescription\", \"addButton\", \"effectiveAtDateField\"];\n static values = {\n wrapperSelector: {\n type: String,\n default: \".nested-form-wrapper\",\n },\n posted: {\n type: Boolean,\n default: false,\n },\n selectedLedgerId: Number,\n };\n\n declare templateTarget: HTMLTemplateElement;\n declare targetTarget: HTMLElement;\n\n declare hasIdTarget: boolean;\n declare idTarget: HTMLSelectElement;\n declare addButtonTarget: HTMLButtonElement;\n declare effectiveAtDateFieldTarget: HTMLInputElement;\n\n declare ledgerEntryRowTargets: HTMLElement[];\n declare ledgerTransactionDescriptionTarget: HTMLTextAreaElement;\n declare ledgerEntryDescriptionTargets: HTMLTextAreaElement[];\n\n declare postedValue: string;\n\n connect() {\n super.connect();\n\n this.applyClasses();\n this.updateAccountUrls();\n this.disableIfPosted();\n }\n\n add(e: Event) {\n e.preventDefault();\n\n const clone = document.importNode(this.templateTarget.content, true) as DocumentFragment;\n\n const elementClone = clone.firstElementChild as HTMLElement | null;\n\n if (elementClone) {\n // Replace the NEW_LEDGER_ENTRY_RECORD placeholder with a unique number for rails to use to determine if the\n // record exists or no (it shouldn't)\n let content = elementClone.innerHTML.replace(/NEW_LEDGER_ENTRY_RECORD/g, new Date().getTime().toString());\n\n if (this.hasIdTarget) {\n content = content.replace(/LEDGER_ID/g, this.idTarget.value);\n }\n\n elementClone.innerHTML = content;\n\n this.targetTarget.insertAdjacentElement(\"beforebegin\", elementClone);\n\n this.applyClasses();\n }\n }\n\n applyClasses() {\n this.ledgerEntryRowTargets.forEach((el, i) => {\n el.classList.add(`ledger-entry-row-${i}`);\n });\n }\n\n updateAccountUrls() {\n const ledgerId = this.idTarget.value;\n\n this.ledgerEntryRowTargets.forEach((el) => {\n el.innerHTML = el.innerHTML.replace(/LEDGER_ID/g, ledgerId);\n });\n }\n\n copyDescription() {\n this.ledgerEntryDescriptionTargets.forEach((el) => {\n el.value = this.ledgerTransactionDescriptionTarget.value;\n });\n }\n\n disableIfPosted() {\n if (this.postedValue) {\n this.idTarget.disabled = true;\n }\n }\n}\n","import NestedForm from 'stimulus-rails-nested-form'\n\nexport default class extends NestedForm {\n connect() {\n super.connect()\n }\n\n remove(e: Event): void {\n super.remove(e);\n this.updateDescriptionSeparatorTitle();\n }\n\n updateDescriptionSeparatorTitle() {\n const titleContainers = document.querySelectorAll('.description-rule-title-container');\n\n const visibleTitleContainers = Array.from(titleContainers).filter(element => {\n return element.parentElement.style.display !== 'none';\n });\n\n visibleTitleContainers[0].classList.add('hidden')\n }\n}\n","import { Toggle } from \"tailwindcss-stimulus-components\";\n\n// Connects to data-controller=\"net-cash-flow-toggle\"\nexport default class extends Toggle {\n static targets = [\"postable\", \"cashAccount\", \"cashAccountWarning\", \"presentationWarning\"];\n\n declare postableTarget: HTMLInputElement;\n declare cashAccountTarget: HTMLInputElement;\n declare cashAccountWarningTarget: HTMLElement;\n declare presentationWarningTarget: HTMLElement;\n\n toggle() {\n if (this.postableTarget.checked && !this.cashAccountTarget.checked) {\n super.show();\n } else {\n super.hide();\n }\n }\n\n showCashAccountWarning() {\n this.cashAccountWarningTarget.classList.remove(\"hidden\")\n }\n\n showPresentationWarning() {\n this.presentationWarningTarget.classList.remove(\"hidden\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { Subscription } from \"@rails/actioncable\";\nimport consumer from \"../channels/consumer\";\n\nexport default class extends Controller {\n static targets = [\"badge\", \"list\", \"placeholder\", \"notification\"];\n static values = {\n accountId: String, // Current account ID\n accountUnread: Number, // Unread count for the current account\n totalUnread: Number, // Unread count across all the user's accounts\n };\n\n declare subscription: Subscription;\n\n declare totalUnreadValue: number;\n declare accountUnreadValue: number;\n declare accountIdValue: string;\n\n declare hasBadgeTarget: boolean;\n declare badgeTarget: HTMLDivElement;\n declare haslistTarget: boolean;\n declare listTarget: HTMLDivElement;\n declare notificationTargets: HTMLDivElement[];\n\n connect() {\n this.subscription = consumer.subscriptions.create(\n { channel: \"NotificationChannel\" },\n {\n connected: this._connected.bind(this),\n disconnected: this._disconnected.bind(this),\n received: this._received.bind(this),\n }\n );\n\n if (this.hasUnread()) this.showUnreadBadge();\n }\n\n disconnect() {\n this.subscription.unsubscribe();\n }\n\n _connected() {}\n\n _disconnected() {}\n\n _received(data) {\n this.totalUnreadValue += 1;\n\n if (data.account_id && data.account_id == this.accountIdValue) {\n this.accountUnreadValue += 1;\n }\n\n // Ignore if user is signed in to a different account\n if (data.account_id && data.account_id != this.accountIdValue) {\n return;\n }\n\n // Regular notifications get added to the navbar\n if (data.html) {\n this.listTarget.insertAdjacentHTML(\"afterbegin\", data.html);\n this.showUnreadBadge();\n }\n }\n\n // Called when the notifications view opens\n open() {\n this.hideUnreadBadge();\n this.markAllAsRead();\n }\n\n hasUnread() {\n return !!this.accountUnreadValue;\n }\n\n showUnreadBadge() {\n if (this.hasBadgeTarget == false) {\n return;\n }\n this.badgeTarget.classList.remove(\"hidden\");\n }\n\n hideUnreadBadge() {\n if (this.hasBadgeTarget == false) {\n return;\n }\n this.badgeTarget.classList.add(\"hidden\");\n }\n\n markAllAsRead() {\n const ids = this.notificationTargets.map((target) => target.dataset.id);\n this.subscription.perform(\"mark_as_read\", { ids: ids });\n\n this.accountUnreadValue = 0;\n this.totalUnreadValue -= ids.length;\n }\n\n markAsInteracted(event) {\n const id = event.currentTarget.dataset.id;\n if (id == null) return;\n this.subscription.perform(\"mark_as_interacted\", { ids: [id] });\n\n // Uncomment to visually mark notification as interacted\n // event.currentTarget.dataset.interactedAt = new Date()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"optional-object\"\nexport default class extends Controller {\n static targets = [\"form\", \"addButton\", \"template\"];\n\n declare formTarget: HTMLDivElement;\n declare hasFormTarget: boolean;\n\n declare addButtonTarget: HTMLDivElement;\n declare hasAddButtonTarget: boolean;\n\n declare templateTarget: HTMLTemplateElement;\n declare hasTemplateTarget: boolean;\n\n connect() {}\n\n add(_e: Event): void {\n if (this.hasFormTarget) {\n const divFromTemplate = this.templateTarget.content.cloneNode(true);\n\n this.formTarget.appendChild(divFromTemplate as Node);\n }\n\n if (this.hasAddButtonTarget) {\n this.addButtonTarget.classList.add(\"hidden\");\n }\n }\n\n remove(_e: Event): void {\n if (this.hasFormTarget) {\n this.formTarget.replaceChildren();\n }\n\n if (this.hasAddButtonTarget) {\n this.addButtonTarget.classList.remove(\"hidden\");\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"ordinal\"\nexport default class extends Controller {\n static targets = [\"ordinal\"];\n\n declare ordinalTargets: HTMLElement[];\n\n ordinalTargetConnected() {\n this.update();\n }\n\n ordinalTargetDisconnected() {\n this.update();\n }\n\n update() {\n this.ordinalTargets.forEach((el, index) => {\n el.textContent = `${index + 1}`;\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\n\n// Connects to data-controller=\"ownership-to-partnership\"\nexport default class extends Controller {\n static targets = [\n \"ownershipRelationships\",\n \"entity\",\n \"startDate\",\n \"endDate\",\n \"partnershipId\",\n \"addAllocationsCheckbox\",\n \"destroy\",\n \"fullConsolidationOwnerAlert\",\n \"fullConsolidationOwnerSelect\",\n \"consolidationMethodRadio\"\n ];\n static values = {\n entity: Number,\n };\n\n declare ownershipRelationshipsTargets: HTMLElement[];\n declare partnershipIdTarget: HTMLInputElement;\n declare entityValue: number;\n declare addAllocationsCheckboxTarget: HTMLInputElement;\n declare fullConsolidationOwnerAlertTarget: HTMLElement;\n declare fullConsolidationOwnerSelectTarget: HTMLSelectElement;\n declare consolidationMethodRadioTargets: HTMLInputElement[];\n\n connect(): void {\n this.identifyOwnerships();\n }\n\n scrollTop(): void {\n window.scrollTo({\n top: 0,\n behavior: \"smooth\"\n });\n }\n\n scrollTopSlideOver(): void {\n const target: HTMLElement = document.querySelector('[data-id=\"slideover-target\"]');\n target.scrollTo({\n top: 0,\n behavior: \"smooth\"\n });\n }\n\n clearValidationErrors(): void {\n this.clearErrorHints()\n this.clearErrorClasses()\n this.clearMainErrorDescription()\n }\n\n clearErrorHints(): void {\n const hintElements: NodeList = document.querySelectorAll('.form-hint.error')\n hintElements.forEach((element: HTMLElement) => { element.remove() })\n }\n\n clearErrorClasses(): void {\n const inputElements: NodeList = document.querySelectorAll('.error')\n if (inputElements.length <= 0) return\n inputElements.forEach((element: HTMLElement) => { element.classList.remove('error') })\n }\n\n clearMainErrorDescription(): void {\n const errorMessageContainer: HTMLElement = document.getElementById('error-messages')\n if (errorMessageContainer == null) return\n errorMessageContainer.remove()\n }\n\n identifyOwnerships() {\n const entityIdsAndNamesForOptions = {};\n const selectedEntityId = this.fullConsolidationOwnerSelectTarget.value;\n\n this.ownershipRelationshipsTargets.forEach((ownershipRelationship) => {\n const entityId = this.getValueForRelationship(ownershipRelationship, \"entityId\");\n\n // If there is an entity id, we allow the user to specify allocations/partnerships\n if (entityId) {\n this.addAllocationsCheckboxTarget.disabled = false;\n\n const destroy = this.getValueForRelationship(ownershipRelationship, \"destroy\");\n if (destroy != \"true\") { // Add the entity name and id as options to the full consolidation owner select\n const entityName = this.getSelectTextForRelationship(ownershipRelationship, \"entityId\");\n entityIdsAndNamesForOptions[entityId] = entityName;\n }\n }\n });\n\n if (this.ownershipRelationshipsTargetsNotSetToBeDestroyed().length > 1 && this.getSelectedConsolidationMethod() === \"full\") {\n this.reloadConsolidationOwnerSelect(entityIdsAndNamesForOptions, selectedEntityId);\n this.fullConsolidationOwnerAlertTarget.classList.remove(\"hidden\");\n } else {\n this.hideAndClearConsolidationOwner();\n }\n }\n\n async addPartnership() {\n const ownerships = [];\n\n this.ownershipRelationshipsTargetsNotSetToBeDestroyed().forEach((ownershipRelationship) => {\n if (ownershipRelationship.children.length == 0) {\n return;\n }\n const entityId = this.getValueForRelationship(ownershipRelationship, \"entityId\");\n\n if (entityId) {\n ownerships.push({\n entity_id: entityId,\n starts_at: this.getValueForRelationship(ownershipRelationship, \"startDate\"),\n ends_at: this.getValueForRelationship(ownershipRelationship, \"endDate\"),\n remove: this.getValueForRelationship(ownershipRelationship, \"destroy\"),\n });\n }\n });\n\n if (ownerships.length > 0) {\n await post(\"/entity_management/partnership_form\", {\n body: {\n id: this.partnershipIdTarget.value || null,\n entity_id: this.entityValue,\n has_partnership_checked: this.addAllocationsCheckboxTarget.checked,\n ownerships: ownerships,\n },\n responseKind: \"turbo-stream\",\n });\n }\n }\n\n getValueForRelationship(ownershipRelationship: HTMLElement, dataTarget: string): string {\n return ownershipRelationship.querySelector(\n `[data-ownership-to-partnership-target=\"${dataTarget}\"]`\n ).value;\n }\n\n getSelectTextForRelationship(ownershipRelationship: HTMLElement, dataTarget: string): string {\n const targetNode = ownershipRelationship.querySelector(\n `[data-ownership-to-partnership-target=\"${dataTarget}\"]`\n );\n\n const selectedOption = targetNode.options[targetNode.selectedIndex];\n return selectedOption.text;\n }\n\n async removeOwnership(event: Event) {\n const ownershipRelationship = (event.target as HTMLElement).closest(\n \"[data-ownership-to-partnership-target='ownershipRelationships']\"\n );\n\n const entityId = this.getValueForRelationship(ownershipRelationship, \"entityId\");\n\n if (entityId) {\n // remove the option for this entity from the full consolidation owner select\n const option = this.fullConsolidationOwnerSelectTarget.querySelector(`option[value=\"${entityId}\"]`);\n option?.remove();\n\n // if there are no options left, disable the checkbox\n if (this.fullConsolidationOwnerSelectTarget.options.length == 0) {\n this.addAllocationsCheckboxTarget.disabled = true;\n }\n }\n\n if (ownershipRelationship) {\n ownershipRelationship.classList.add(\"hidden\");\n }\n\n this.setValueForRelationship(ownershipRelationship, \"destroy\", \"true\");\n\n // hide the full consolidation owner select if there are less than 2 owners after removing this one\n if (this.ownershipRelationshipsTargetsNotSetToBeDestroyed().length < 2) {\n this.hideAndClearConsolidationOwner();\n }\n\n this.addPartnership();\n }\n\n ownershipRelationshipsTargetsNotSetToBeDestroyed(): HTMLElement[] {\n return this.ownershipRelationshipsTargets.filter((ownershipRelationship) => {\n return this.getValueForRelationship(ownershipRelationship, \"destroy\") !== \"true\";\n });\n }\n\n setValueForRelationship(ownershipRelationship: HTMLElement, dataTarget: string, value: string) {\n const targetNode = ownershipRelationship.querySelector(\n `[data-ownership-to-partnership-target=\"${dataTarget}\"]`\n ) as HTMLInputElement;\n\n targetNode.value = value;\n }\n\n addOptionToFullConsolidationOwnerSelect(value, text, selected: boolean = false) {\n const option = document.createElement(\"option\");\n option.value = value;\n option.text = text;\n option.selected = selected;\n this.fullConsolidationOwnerSelectTarget.add(option);\n }\n\n hideAndClearConsolidationOwner() {\n this.fullConsolidationOwnerSelectTarget.innerHTML = \"\";\n this.addOptionToFullConsolidationOwnerSelect(\"\", \"\");\n this.fullConsolidationOwnerSelectTarget.value = \"\";\n this.fullConsolidationOwnerAlertTarget.classList.add(\"hidden\");\n }\n\n reloadConsolidationOwnerSelect(entityIdsAndNamesForOptions: object, selectedEntityId: string) {\n if (Object.keys(entityIdsAndNamesForOptions).length > 0) {\n this.fullConsolidationOwnerSelectTarget.innerHTML = \"\";\n\n const entityIdsToAddToOptions = Object.keys(entityIdsAndNamesForOptions);\n entityIdsToAddToOptions.forEach((entityId) => {\n const isSelected = entityId === selectedEntityId;\n this.addOptionToFullConsolidationOwnerSelect(entityId, entityIdsAndNamesForOptions[entityId], isSelected);\n });\n }\n }\n\n getSelectedConsolidationMethod(): string | undefined {\n return Array.from(this.consolidationMethodRadioTargets).find(r => r.checked)?.value;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"payable\"\nexport default class extends Controller {\n static targets = [\n \"differenceAmountFooter\",\n \"invoiceIdentifier\",\n \"payableLineItemAmount\",\n \"payee\",\n \"totalAmount\",\n \"totalAmountFooter\"\n ];\n\n declare differenceAmountFooterTarget: HTMLElement;\n declare invoiceIdentifierTarget: HTMLInputElement;\n declare payableLineItemAmountTargets: HTMLInputElement[];\n declare payeeTarget: HTMLSelectElement;\n declare totalAmountTarget: HTMLInputElement;\n declare totalAmountFooterTarget: HTMLElement;\n\n connect() {\n const payeeName = this.payeeTarget.selectedOptions[0].text;\n const invoiceIdentifier = this.invoiceIdentifierTarget.value;\n\n if (payeeName != \"\" && invoiceIdentifier == \"\") {\n this.generateInvoiceIdentifier();\n }\n }\n\n generateInvoiceIdentifier() {\n const payeeName = this.payeeTarget.selectedOptions[0].text;\n\n if (payeeName != \"\") {\n const payeeNamePrefix = payeeName.substring(0, 3).toUpperCase();\n const randomHexString = [...Array(6)].map(() => Math.floor(Math.random() * 16).toString(16)).join('').toUpperCase();\n this.invoiceIdentifierTarget.value = `${payeeNamePrefix}-${randomHexString}`;\n }\n }\n\n payableLineItemAmountTargetDisconnected() {\n this.updateDifferenceAmountFooter();\n }\n\n updateTotalAmountFooter() {\n this.totalAmountFooterTarget.textContent = `Total: ${this.totalAmountTarget.value}`;\n this.updateDifferenceAmountFooter();\n }\n\n updateDifferenceAmountFooter() {\n const payableLineItemsSum = this.payableLineItemAmountTargets.reduce((total, input) => {\n const value = this.convertCurrencyStringToNumber(input.value);\n return total + (isNaN(value) ? 0 : value);\n }, 0);\n const totalAmount = this.convertCurrencyStringToNumber(this.totalAmountTarget.value);\n const differenceAmount = totalAmount - payableLineItemsSum;\n\n if (differenceAmount == 0) {\n this.differenceAmountFooterTarget.textContent = \"\";\n } else {\n const label = differenceAmount > 0 ? \"Missing\" : \"Excess\";\n const formattedDifferenceAmount = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n }).format(Math.abs(differenceAmount));\n \n this.differenceAmountFooterTarget.textContent = `${label}: ${formattedDifferenceAmount}`;\n }\n }\n\n convertCurrencyStringToNumber(value: string) {\n return Number(value.replace(/[^0-9.-]+/g,\"\"));\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post, destroy } from \"@rails/request.js\";\n\n// Connects to data-controller=\"payable-line-items\"\nexport default class extends Controller {\n static targets = [\"vendorSelect\", \"lineItem\", \"accountCodeInput\", \"tagInput\"];\n\n declare vendorSelectTarget: HTMLSelectElement;\n declare selectedVendorIdValue: string;\n declare lineItemTargets: HTMLElement[];\n declare accountCodeInputTargets: HTMLElement[];\n declare tagInputTargets: HTMLElement[];\n declare hasLineItemTarget: boolean;\n\n vendorSelectTargetConnected(element) {\n const value = element.selectedOptions[0].value;\n this.selectedVendorIdValue = value;\n }\n\n vendorSelected(event: Event) {\n const input = event.target as HTMLInputElement;\n const value = input.value;\n\n this.selectedVendorIdValue = value;\n this.updateLineItems(event);\n }\n\n lineItemId(element) {\n const input = element.querySelector(\n `#payable_payable_line_items_attributes_${element.dataset.lineItemIndex}_id`\n ) as HTMLInputElement\n return input.value;\n }\n\n updateLineItems(_event?: Event) {\n let lineItemIndexes = [];\n let lineItemIds = [];\n if (this.hasLineItemTarget) {\n lineItemIndexes = this.lineItemTargets.map( (lineItem: HTMLDivElement) => {\n return parseInt(lineItem.dataset.lineItemIndex);\n });\n lineItemIds = this.lineItemTargets.map( (lineItem: HTMLDivElement) => {\n return parseInt(this.lineItemId(lineItem));\n });\n }\n\n post(this.vendorSelectTarget.dataset.lineItemUrl, {\n body: {\n turbo_stream_action: \"replace\",\n indexes: lineItemIndexes,\n line_item_ids: lineItemIds,\n vendor_id: this.selectedVendorIdValue,\n },\n responseKind: \"turbo-stream\",\n });\n }\n\n addLineItem(event: Event) {\n event.preventDefault();\n const button = event.currentTarget as HTMLButtonElement;\n\n post(button.dataset.url, {\n body: {\n turbo_stream_action: \"append\",\n index: parseInt(button.dataset.index),\n vendor_id: this.selectedVendorIdValue,\n },\n responseKind: \"turbo-stream\",\n });\n }\n\n removeLineItem(event: Event) {\n event.preventDefault();\n const button = event.currentTarget as HTMLButtonElement;\n\n destroy(button.dataset.url, {\n body: { line_item_id: parseInt(button.dataset.lineItemId) },\n responseKind: \"turbo-stream\",\n });\n }\n}\n","export const toggleButton = (buttonTargets: HTMLButtonElement[], event: object) => {\n let count = 0;\n let removeMiddleBorder = false;\n const totalButtons = buttonTargets.length;\n\n buttonTargets.forEach(target => {\n // @ts-ignore\n if (target === event.target) {\n target.classList.remove(\"btn-white\");\n target.classList.add(\"bg-cyan-600\", \"focus:ring-cyan-500\", \"text-white\", \"focus:text-white\", \"hover:text-white\", \"hover:bg-sumit-primary-cyan\");\n\n if (count !== 0 && count !== totalButtons - 1) {\n removeMiddleBorder = true;\n }\n } else {\n target.classList.remove(\"bg-cyan-600\", \"focus:ring-cyan-500\", \"text-white\", \"focus:text-white\", \"hover:text-white\", \"hover:bg-sumit-primary-cyan\" );\n target.classList.add(\"btn-white\");\n }\n\n count++;\n });\n\n if (removeMiddleBorder && totalButtons > 2) {\n for (let i = 1; i < totalButtons - 1; i++) {\n buttonTargets[i].classList.add(\"border-l-0\");\n }\n\n buttonTargets[totalButtons - 1].classList.remove(\"border-l-0\");\n }\n};\n","import { Controller } from \"@hotwired/stimulus\"\nimport { toggleButton } from \"../helpers/button_helpers\"\n\n// Connects to data-controller=\"payable-type\"\nexport default class extends Controller {\n declare buttonTargets: HTMLButtonElement[]\n declare hiddenTypeInputTarget: HTMLInputElement;\n\n static targets = ['button', 'hiddenTypeInput']\n\n selectedButton: HTMLButtonElement | null = null;\n\n toggleButton(event: Event) {\n if (this.selectedButton === event.target) {\n this.selectedButton = this.buttonTargets[0];\n toggleButton(this.buttonTargets, { target: this.buttonTargets[0] });\n this.hiddenTypeInputTarget.value = null;\n } else {\n this.selectedButton = event.target as HTMLButtonElement;\n toggleButton(this.buttonTargets, event);\n this.hiddenTypeInputTarget.value = this.selectedButton.id.replace(\"payables-status-\", \"\");\n }\n\n this.dispatch(\"statusUpdated\");\n }\n}","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"payment-terms\"\nexport default class extends Controller {\n static targets = [\"paymentTerms\", \"invoiceDate\", \"dueDate\"];\n\n declare hasPaymentTermsTarget: boolean;\n declare paymentTermsTarget: HTMLSelectElement;\n declare hasInvoiceDateTarget: boolean;\n declare invoiceDateTarget: HTMLInputElement;\n declare hasDueDateTarget: boolean;\n declare dueDateTarget: HTMLInputElement;\n\n connect() {}\n\n getPaymentTermsNetDays() {\n if (!this.hasPaymentTermsTarget) { return null; }\n const netDays = this.paymentTermsTarget.selectedOptions[0].dataset.netDays;\n return parseInt(netDays) || null;\n }\n\n calculateNetDate(invoiceDate, daysToAdd) {\n const netDate = invoiceDate;\n netDate.setDate(netDate.getDate() + daysToAdd);\n return netDate;\n }\n\n dateToISO(date) {\n return date.toISOString().split('T')[0];\n }\n\n convertToDate(dateString) {\n const parts = dateString.split('-');\n return new Date(parts[0], parts[1] - 1, parts[2]); // Note: Subtracting 1 from the month because JavaScript months are 0-based\n }\n\n updatePaymentTerms(option) {\n if (this.hasPaymentTermsTarget) {\n this.paymentTermsTarget.value = option\n }\n }\n\n updateDueDate() {\n if (!this.hasInvoiceDateTarget || !this.invoiceDateTarget.value) { return; }\n\n const invoiceDate = this.convertToDate(this.invoiceDateTarget.value);\n\n if (this.hasPaymentTermsTarget && this.paymentTermsTarget.value == 'due_on_receipt') {\n this.dueDateTarget.value = this.dateToISO(invoiceDate);\n return;\n }\n\n const paymentTermsDays = this.getPaymentTermsNetDays();\n const netDate = this.calculateNetDate(invoiceDate, paymentTermsDays);\n\n if (!paymentTermsDays) { return; }\n\n if (this.hasDueDateTarget) {\n this.dueDateTarget.value = this.dateToISO(netDate);\n }\n }\n\n handlePaymentTermsChange() {\n this.updateDueDate();\n }\n\n handleDueDateChange() {\n this.updatePaymentTerms('other');\n }\n\n handleInvoiceDateChange() {\n this.updateDueDate();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\nimport { Plaid as PlaidTypes } from \"plaid-link\";\n\nconst INVALID_LINK_TOKEN_ERROR_CODE = \"INVALID_LINK_TOKEN\";\nconst LINK_TOKEN_LOCAL_STORAGE_KEY = \"linkTokenData\";\nconst OAUTH_STATE_ID_PARAM = \"oauth_state_id\";\n\n// Connects to data-controller=\"plaid\"\nexport default class extends Controller {\n static targets = [\"publicTokenInput\", \"metadataInput\"];\n static values = { linkTokenUrl: String };\n\n declare linkHandler: PlaidTypes.LinkHandler;\n declare linkTokenUrlValue: string;\n declare publicTokenInputTarget: HTMLInputElement;\n declare metadataInputTarget: HTMLInputElement;\n\n connect() {\n const linkTokenData = localStorage.getItem(LINK_TOKEN_LOCAL_STORAGE_KEY);\n const oauthStateIdParam = new URL(window.location.toString()).searchParams.get(OAUTH_STATE_ID_PARAM);\n\n if (linkTokenData != null && oauthStateIdParam != null) {\n // This block is entered after completing the OAuth redirect flow,\n // which only happens when Link is initialized in a webview and when\n // the institution supports/requires OAuth\n\n // Plaid is imported through their CDN as a script tag on the HTML page. So when\n // using this be sure to add it to the header tag (as in\n // app/views/connections/index.html.erb).\n // @ts-ignore\n this.linkHandler = Plaid.create({\n token: JSON.parse(linkTokenData).link_token,\n receivedRedirectUri: window.location.href,\n onSuccess: this.onSuccess,\n onExit: this.onExit,\n }) as PlaidTypes.LinkHandler;\n\n this.linkHandler.open();\n } else {\n return;\n }\n }\n\n async addConnection() {\n // @ts-ignore\n this.linkHandler = Plaid.create({\n token: (await this.createLinkToken()).link_token,\n onSuccess: this.onSuccess,\n onExit: this.onExit,\n }) as PlaidTypes.LinkHandler;\n\n this.linkHandler.open();\n }\n\n async createLinkToken() {\n const response = await post(this.linkTokenUrlValue);\n const linkTokenData = response.json;\n\n if (response.ok) {\n localStorage.setItem(LINK_TOKEN_LOCAL_STORAGE_KEY, JSON.stringify(linkTokenData));\n }\n\n return linkTokenData;\n }\n\n onSuccess = (publicToken, metadata) => {\n localStorage.removeItem(LINK_TOKEN_LOCAL_STORAGE_KEY);\n // Send the public_token to server.\n this.publicTokenInputTarget.value = publicToken;\n this.metadataInputTarget.value = JSON.stringify(metadata);\n this.element.requestSubmit();\n };\n\n onExit = async (err, _metadata) => {\n localStorage.removeItem(LINK_TOKEN_LOCAL_STORAGE_KEY);\n // The user exited the Link flow with an INVALID_LINK_TOKEN error. This can happen if the\n // token expires or the user has attempted too many invalid logins.\n if (err != null && err.error_code === INVALID_LINK_TOKEN_ERROR_CODE) {\n this.linkHandler.destroy();\n // @ts-ignore\n this.linkHandler = Plaid.create({\n // Fetch a new link_token because the old one was invalidated.\n token: (await this.createLinkToken()).link_token,\n onSuccess: this.onSuccess,\n onExit: this.onExit,\n }) as PlaidTypes.LinkHandler;\n }\n // Note: metadata contains the most recent API request ID and the Link session ID.\n // Storing this information could be helpful for support.\n };\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { post } from \"@rails/request.js\";\nimport { Plaid as PlaidTypes } from \"plaid-link\";\n\nconst LINK_TOKEN_LOCAL_STORAGE_KEY = \"linkTokenData\";\n\nexport default class extends Controller {\n static targets = [\"metadataInput\"];\n static values = { linkTokenUrl: String };\n\n declare linkTokenUrlValue: string;\n declare linkHandler: PlaidTypes.LinkHandler;\n declare metadataInputTarget: HTMLInputElement;\n\n async updateConnection() {\n // @ts-ignore\n this.linkHandler = Plaid.create({\n token: (await this.createLinkToken()).link_token,\n onSuccess: this.onSuccess,\n onExit: this.onExit,\n }) as PlaidTypes.LinkHandler;\n\n this.linkHandler.open();\n }\n\n async createLinkToken() {\n const response = await post(this.linkTokenUrlValue);\n const linkTokenData = response.json;\n\n if (response.ok) {\n localStorage.setItem(LINK_TOKEN_LOCAL_STORAGE_KEY, JSON.stringify(linkTokenData));\n }\n\n return linkTokenData;\n }\n\n onSuccess = (_publicToken, metadata) => {\n localStorage.removeItem(LINK_TOKEN_LOCAL_STORAGE_KEY);\n this.metadataInputTarget.value = JSON.stringify(metadata);\n this.element.requestSubmit();\n };\n\n onExit = (_err, _metadata) => {\n localStorage.removeItem(LINK_TOKEN_LOCAL_STORAGE_KEY);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n declare allSelectedValue: string;\n declare selectAllTargets: HTMLInputElement[];\n declare radioTargets: HTMLInputElement[];\n\n static targets = [\"selectAll\", \"radio\"];\n static values = {\n allSelected: String\n };\n\n allSelectedValueChanged() {\n this.selectAllTargets.forEach((radio) => {\n if (radio.value == this.allSelectedValue) {\n radio.checked = true;\n } else {\n radio.checked = false;\n }\n });\n\n this.radioTargets.forEach((radio) => {\n if (radio.value == this.allSelectedValue) {\n radio.checked = true;\n }\n });\n }\n\n allMatchingRadioTargetsAreSelected(value) {\n return this.radioTargets.filter(radio => radio.value == value).every(radio => radio.checked);\n }\n\n selectAll(event) {\n this.allSelectedValue = event.target.value;\n }\n\n updateSelectAllTargets(event) {\n if (this.allMatchingRadioTargetsAreSelected(event.target.value)) {\n this.allSelectedValue = event.target.value;\n } else {\n this.allSelectedValue = \"\";\n }\n }\n}\n","import CheckboxSelectAll from \"stimulus-checkbox-select-all\";\nimport { post } from \"@rails/request.js\";\n\nexport default class extends CheckboxSelectAll {\n declare checkboxTargets: HTMLInputElement[];\n\n static values = {\n updateSelectedUrl: String\n };\n\n declare hasUpdateSelectedUrlValue: boolean;\n declare updateSelectedUrlValue: string | undefined;\n\n toggle(e: Event): void {\n e.preventDefault()\n\n // @ts-ignore\n const isChecked = e.target.checked;\n\n const ledgerEntryIds = [];\n this.checkboxTargets.forEach(checkbox => {\n checkbox.checked = isChecked;\n ledgerEntryIds.push(checkbox.value);\n })\n\n post(this.updateSelectedUrlValue, {\n body: JSON.stringify(\n {\n \"reconciliation\": {\n \"ledger_entry_ids\": ledgerEntryIds,\n \"selected\": isChecked\n }\n }\n ),\n responseKind: \"turbo-stream\",\n });\n // @ts-ignore\n this.dispatch(\"checked\")\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { get, post } from \"@rails/request.js\";\n\n// Connects to data-controller=\"reconciliation\"\nexport default class extends Controller {\n static targets = [\"accountIdInput\", \"startDateInput\"];\n\n static values = {\n startingBalanceUrl: String,\n updateSelectedUrl: String,\n startingDateUrl: String,\n };\n\n declare accountIdInputTarget: HTMLInputElement;\n declare hasAccountIdInputTarget: boolean;\n declare hasStartDateInputTarget: boolean;\n declare startDateInputTarget: HTMLInputElement;\n declare startingBalanceInputTarget: HTMLInputElement;\n\n declare hasStartingBalanceUrlValue: boolean;\n declare startingBalanceUrlValue: string;\n declare hasUpdateSelectedUrlValue: boolean;\n declare updateSelectedUrlValue: string;\n declare hasStartingDateUrlValue: boolean;\n declare startingDateUrlValue: string;\n\n updateSelected(event) {\n if (this.hasUpdateSelectedUrlValue) {\n post(this.updateSelectedUrlValue, {\n body: JSON.stringify({\n reconciliation: {\n ledger_entry_ids: [event.currentTarget.value],\n selected: event.currentTarget.checked,\n },\n }),\n responseKind: \"turbo-stream\",\n });\n }\n }\n\n updateStartingDate(event: Event) {\n if (event.target == this.startDateInputTarget) {\n return;\n }\n\n if (this.hasStartingDateUrlValue) {\n get(this.startingDateUrlValue, {\n query: {\n account_id: this.accountIdInputTarget.value,\n },\n responseKind: \"turbo-stream\",\n });\n }\n }\n\n accountIdInputTargetConnected() {\n this.updateStartingBalance();\n }\n\n startDateInputTargetConnected() {\n this.updateStartingBalance();\n }\n\n async handleAccountUpdate(event) {\n this.updateStartingDate(event);\n this.updateStartingBalance();\n }\n\n async updateStartingBalance() {\n if (\n this.hasStartingBalanceUrlValue &&\n this.hasAccountIdInputTarget &&\n this.hasStartDateInputTarget\n ) {\n await get(this.startingBalanceUrlValue, {\n query: { account_id: this.accountIdInputTarget.value, start_date: this.startDateInputTarget.value },\n responseKind: \"turbo-stream\",\n });\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"removable\"\nexport default class extends Controller {\n static targets = [\"removable\", \"removeButton\"];\n\n declare removableTargets: HTMLElement[];\n declare removeButtonTargets: HTMLButtonElement[];\n\n connect(): void {\n this.setButtonStates();\n }\n\n removeElement(event) {\n event.preventDefault();\n\n const id = event.params.id;\n const target = this.removableTargets.find((el) => el.id === id);\n\n if (target) {\n target.remove();\n\n this.setButtonStates();\n }\n }\n\n setButtonStates() {\n if (this.removableTargets.length === 1) {\n this.removeButtonTargets.forEach((button) => {\n button.disabled = true;\n button.classList.add(\"hidden\");\n });\n } else {\n this.removeButtonTargets.forEach((button) => {\n button.disabled = false;\n button.classList.remove(\"hidden\");\n });\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport {\n GridOptions,\n RowNode,\n IAggFuncParams,\n SortDirection,\n createGrid,\n ColumnPinnedType,\n RowGroupingDisplayType,\n GetRowIdParams,\n ToolPanelDef,\n GetContextMenuItemsParams,\n MenuItemDef,\n GridApi,\n ValueGetterParams,\n ColDef,\n RowClassParams,\n} from \"ag-grid-enterprise\";\nimport {\n AccountCellRenderer,\n FlattenedAccountCellRenderer,\n NumberCellRenderer,\n tagHeaderTemplate,\n consolidatedHeaderTemplate,\n HeaderGroupRenderer,\n} from \"../helpers/reports/renderers\";\nimport { processSavedReport, saveReportTemplate, updateSavedReportTemplate } from \"../helpers/reports/saved_reports\";\nimport {\n defaultExportParams,\n getClassesForAccounts,\n getClassesForCells,\n excelStyles,\n headerRows,\n} from \"../helpers/reports/excel_options\";\nimport { dataTypeDefinitions, formatDateForDisplay } from \"../helpers/reports/formatters\";\nimport { aggColumnValues } from \"../helpers/reports\";\nimport { LoadingOverlay, NoRowsOverlay } from \"../helpers/reports/overlays\";\nimport { isGroupHeader } from \"../helpers/reports/node_helpers\";\nimport {\n calculatePercentChangeTotal,\n validateDateSelected,\n setDateAndAlertDisplay,\n requestReportData,\n processReportDataResponse,\n validateEntitySet,\n hasOption,\n getOptionState,\n numberValueGetter,\n updateBreadcrumb,\n shouldRefreshGrouping,\n} from \"../helpers/reports/utils\";\nimport { RowData, IGridOptionsValue, ServerProvidedColDef, ReportOption, ReportType } from \"../types\";\nimport {\n getCheckboxValues,\n setOptionsCheckboxValue,\n setCheckboxValues,\n setSelectValues,\n getSelectValues,\n} from \"../helpers/reports/index\";\nimport { loadDateInputs, prepareDateRangeOptions } from \"../helpers/relative_dates\";\n\n// Connects to data-controller=\"reporting\"\nexport default class extends Controller {\n totalCols = new Set() as Set;\n consolidatedCols = new Set() as Set;\n options = {};\n\n static targets = [\n \"form\",\n \"grid\",\n \"dateRange\",\n \"startDate\",\n \"endDate\",\n \"ledgers\",\n \"compareable\",\n \"option\",\n \"mergeEntitiesToggle\",\n \"ledgers\",\n \"compareToLastPeriod\",\n \"colTag\",\n \"rowTag\",\n \"rowTagsButton\",\n \"accountCode\",\n \"intervalSelect\",\n \"consolidationFormatSelect\",\n \"ledgerErrors\",\n \"dateErrors\",\n \"exportButton\",\n \"updateReportButton\",\n \"saveReportButton\",\n \"dateDisplay\",\n \"alertDisplay\",\n \"saveReportName\",\n \"saveReportType\",\n ];\n\n static values = {\n gridOptions: Object,\n reportType: String,\n enableGroupSubTotals: {\n type: Boolean,\n default: true,\n },\n reportTemplateId: String,\n // We asynchronously load account codes and tags, so we need to know when we are done loading them\n asyncInputsLoaded: {\n type: Boolean,\n default: false,\n },\n };\n\n // Targets\n declare gridTarget: HTMLDivElement;\n declare formTarget: HTMLFormElement;\n declare ledgersTarget: HTMLSelectElement;\n declare ledgerErrorsTarget: HTMLSpanElement;\n declare dateErrorsTarget: HTMLSpanElement;\n declare optionTargets: HTMLInputElement[];\n declare hasMergeEntitiesToggleTarget: boolean;\n declare mergeEntitiesToggleTarget: HTMLInputElement;\n\n declare dateRangeTarget: HTMLSelectElement;\n declare hasDateRangeTarget: boolean;\n declare startDateTarget: HTMLInputElement;\n declare hasStartDateTarget: boolean;\n declare endDateTarget: HTMLInputElement;\n declare hasEndDateTarget: boolean;\n declare compareableTarget: HTMLInputElement;\n declare hasCompareableTarget: boolean;\n declare compareToLastPeriodTarget: HTMLInputElement;\n declare hasCompareToLastPeriodTarget: boolean;\n declare intervalSelectTarget: HTMLSelectElement;\n declare hasIntervalSelectTarget: boolean;\n declare consolidationFormatSelectTarget: HTMLSelectElement;\n declare hasConsolidationFormatSelectTarget: boolean;\n\n declare colTagTargets: HTMLInputElement[];\n declare rowTagTargets: HTMLInputElement[];\n declare rowTagsButtonTarget: HTMLButtonElement;\n declare hasRowTagsButtonTarget: boolean;\n declare accountCodeTargets: HTMLInputElement[];\n\n declare dateDisplayTarget: HTMLDivElement;\n declare alertDisplayTarget: HTMLSpanElement;\n\n declare exportButtonTarget: HTMLButtonElement;\n declare hasExportButtonTarget: boolean;\n\n declare updateReportButtonTarget: HTMLButtonElement;\n declare saveReportButtonTarget: HTMLButtonElement;\n declare hasUpdateReportButtonTarget: boolean;\n declare hasSaveReportButtonTarget: boolean;\n\n declare saveReportNameTarget: HTMLInputElement;\n declare saveReportTypeTarget: HTMLInputElement;\n\n // Values\n declare gridOptionsValue: IGridOptionsValue;\n declare reportTypeValue: string;\n declare hasReportTypeValue: boolean;\n declare enableGroupSubTotalsValue: boolean;\n declare reportTemplateIdValue: string;\n\n // Local variables\n declare gridApi: GridApi;\n declare gridOptions: GridOptions;\n\n declare asyncInputsLoadedValue: boolean;\n\n connect() {\n this.gridTarget.classList.remove(\"loaded\");\n\n // Ensure the export button is disabled until the grid is loaded\n if (this.hasExportButtonTarget) {\n this.exportButtonTarget.disabled = true;\n }\n if (this.hasSaveReportButtonTarget) {\n this.saveReportButtonTarget.disabled = true;\n }\n\n this.gridOptions = {\n columnDefs: null,\n headerHeight: this.consolidatedReport() ? 100 : 40,\n aggFuncs: { aggPercentChangeTotal: this.aggPercentChangeTotal },\n defaultColDef: {\n // allow every column to be aggregated\n enableValue: true,\n // allow every column to be grouped\n enableRowGroup: true,\n suppressHeaderFilterButton: true,\n },\n getContextMenuItems: (_params: GetContextMenuItemsParams) => {\n // Removing the export option since we have the api call to export\n const result: (string | MenuItemDef)[] = [\n \"autoSizeAll\",\n \"separator\",\n \"expandAll\",\n \"contractAll\",\n \"separator\",\n \"copy\",\n \"copyWithHeaders\",\n \"copyWithGroupHeaders\",\n ];\n\n return result;\n },\n excelStyles: excelStyles,\n autoGroupColumnDef: this.accountGroupColumnDefinition,\n groupDisplayType: \"singleColumn\" as RowGroupingDisplayType,\n suppressMoveWhenRowDragging: true,\n rowData: null,\n // enable Tree Data mode\n treeData: true,\n // expand all groups by default\n groupDefaultExpanded: -1,\n getDataPath: (data: RowData) => {\n return data.accountBreadCrumbs;\n },\n getRowId: (params: GetRowIdParams) => {\n return params.data.id.toString();\n },\n statusBar: {\n statusPanels: [\n { statusPanel: \"agTotalAndFilteredRowCountComponent\", align: \"left\" },\n { statusPanel: \"agTotalRowCountComponent\", align: \"center\" },\n { statusPanel: \"agFilteredRowCountComponent\" },\n { statusPanel: \"agSelectedRowCountComponent\" },\n { statusPanel: \"agAggregationComponent\" },\n ],\n },\n sideBar: {\n toolPanels: [\n {\n id: \"columns\",\n labelDefault: \"Columns\",\n labelKey: \"columns\",\n iconKey: \"columns\",\n toolPanel: \"agColumnsToolPanel\",\n toolPanelParams: {\n suppressPivots: true,\n suppressPivotMode: true,\n },\n } as ToolPanelDef,\n ],\n },\n allowContextMenuWithControlKey: true,\n // adds subtotals\n groupTotalRow: \"bottom\",\n grandTotalRow: this.reportTypeValue === \"trial_balance\" ? \"bottom\" : null,\n dataTypeDefinitions: {\n ...dataTypeDefinitions,\n },\n getRowStyle: (params: RowClassParams) => {\n let rowStyles = {};\n const node = params.node as RowNode;\n const level = node.level;\n\n if (node.hasChildren() || node.rowPinned) {\n rowStyles = {\n \"font-weight\": 700,\n };\n }\n\n if (node.hasChildren() && node.footer) {\n const isRootLevel = level === -1;\n\n if (isRootLevel) {\n return Object.assign(rowStyles, { \"background-color\": \"#CCE7EA\", \"border-top\": \"1px solid black\" });\n } else if (level === 0) {\n return Object.assign(rowStyles, {\n \"background-color\": \"#e5e7eb\",\n \"border-top\": \"1px solid black\",\n \"border-bottom\": \"1px solid black\",\n });\n } else {\n return Object.assign(rowStyles, { \"border-top\": \"1px solid black\", \"border-bottom\": \"1px solid black\" });\n }\n } else if (node.data?.metadata?.generated_total_row) {\n return Object.assign(rowStyles, {\n \"background-color\": \"#e5e7eb\",\n \"border-top\": \"1px solid black\",\n \"border-bottom\": \"1px solid black\",\n });\n }\n return rowStyles;\n },\n noRowsOverlayComponent: NoRowsOverlay,\n loadingOverlayComponent: LoadingOverlay,\n components: {\n accountCellRenderer: AccountCellRenderer,\n flattenedAccountCellRenderer: FlattenedAccountCellRenderer,\n },\n onRowDataUpdated: () => {\n this.gridTarget.classList.add(\"loaded\");\n },\n cellSelection: true,\n };\n\n // update additional custom options from gridOptions\n for (const option in this.gridOptionsValue) {\n // eslint-disable-next-line no-prototype-builtins\n if (!this.gridOptions.hasOwnProperty(option)) {\n continue;\n }\n\n this.gridOptions[option] = this.gridOptionsValue[option];\n }\n\n if (this.reportTemplateIdValue) {\n processSavedReport(this, this.reportTemplateIdValue);\n } else if (this.gridOptionsValue.autoLoadReport) {\n this.createGrid();\n this.loadGridData(new Event(\"autoload\"));\n } else {\n // Clear the report options from session storage to avoid loading old options\n sessionStorage.removeItem(this.sessionStorageKey(\"report_options\"));\n this.createGrid();\n }\n }\n\n createGrid() {\n this.gridApi = createGrid(this.gridTarget, this.gridOptions);\n this.gridApi.showNoRowsOverlay();\n }\n\n // We need to set the grid state before the grid is created in order for it to work.\n // Currently there is no way to update the state after the grid had been initialized.\n // State is set using initialState: https://github.com/ag-grid/ag-grid/issues/7445\n loadAgGridState(agGridState) {\n if (agGridState) {\n this.gridOptions.initialState = agGridState;\n\n // Rely on the state to expand groups by default\n this.gridOptions.groupDefaultExpanded = 0;\n }\n }\n\n disconnect() {\n if (this.gridApi) {\n this.gridApi.destroy();\n }\n }\n\n async loadGridData(event: Event) {\n this.gridApi.setGridOption(\"loading\", true);\n this.gridTarget.classList.remove(\"loaded\");\n\n this.addAutoLoadParamToUrl();\n\n if (!this.optionTargets.includes(event.currentTarget as HTMLInputElement)) {\n event.preventDefault();\n }\n\n this.totalCols.clear();\n\n const sessionReportOptions = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n\n if (event.type == \"autoload\" && sessionReportOptions) {\n this.loadValuesToInputs(sessionReportOptions);\n }\n\n if (!this.validateEntitySetIfConsolidatedReport()) {\n return;\n }\n\n if (!validateDateSelected(this)) {\n return;\n }\n\n // we do this for account codes and tags here because now they are loaded asynchronously\n // and might not be available at the time of the run. Then we use the turbo:frame-render event on\n // _augment_options_slideover partial to call loadAsyncInputs()\n let accountCodeIds = [];\n let colTagIds = [];\n let rowTagIds = [];\n let groupByAccountCodes = {};\n let groupByTags = {};\n\n if (this.asyncInputsLoadedValue) {\n accountCodeIds = getCheckboxValues(this.accountCodeTargets);\n colTagIds = getCheckboxValues(this.colTagTargets);\n rowTagIds = getCheckboxValues(this.rowTagTargets);\n } else {\n accountCodeIds = sessionReportOptions?.account_code_ids;\n\n if (sessionReportOptions?.col_tag_ids) {\n colTagIds = sessionReportOptions.col_tag_ids;\n } else if (sessionReportOptions?.tag_ids) {\n colTagIds = sessionReportOptions.tag_ids;\n }\n\n rowTagIds = sessionReportOptions?.row_tag_ids;\n\n if (!Object.prototype.hasOwnProperty.call(this.getOptionsObject(), \"group_by_account_codes\")) {\n groupByAccountCodes = { group_by_account_codes: sessionReportOptions?.group_by_account_codes };\n }\n if (!Object.prototype.hasOwnProperty.call(this.getOptionsObject(), \"group_by_account_codes\")) {\n groupByTags = { group_by_tags: sessionReportOptions?.group_by_tags };\n }\n }\n\n const body = {\n start_date: this.hasStartDateTarget ? this.startDateTarget.value : null,\n end_date: this.hasEndDateTarget ? this.endDateTarget.value : null,\n date_range: this.hasDateRangeTarget ? this.dateRangeTarget.value : null,\n interval: this.hasIntervalSelectTarget ? this.intervalSelectTarget.value : null,\n consolidation_format: this.hasConsolidationFormatSelectTarget ? this.consolidationFormatSelectTarget.value : null,\n comparable: this.hasCompareableTarget ? this.compareableTarget.value : null,\n compare_to_last_period: this.hasCompareToLastPeriodTarget ? this.compareToLastPeriodTarget.checked : null,\n ledger_ids: getSelectValues(this.ledgersTarget),\n account_code_ids: accountCodeIds,\n col_tag_ids: colTagIds,\n row_tag_ids: rowTagIds,\n ...groupByAccountCodes,\n ...groupByTags,\n ...this.getOptionsObject(),\n };\n\n if (event.type == \"click\") {\n sessionStorage.setItem(this.sessionStorageKey(\"report_options\"), JSON.stringify(body));\n }\n\n const response = await requestReportData(body);\n\n processReportDataResponse(this, response, (data) => {\n this.renderGrid(data);\n });\n }\n\n updateBreadcrumb(event: Event) {\n const element = event.srcElement as HTMLElement;\n\n updateBreadcrumb(this.reportTemplateIdValue, element);\n }\n\n addAutoLoadParamToUrl() {\n // Skip if the url has the auto_load or report_template_id params\n if (window.location.search.includes(\"auto_load\") || window.location.search.includes(\"report_template_id\")) {\n return;\n }\n\n const url = new URLSearchParams(window.location.search);\n url.set(\"auto_load\", \"true\");\n window.history.replaceState({}, document.title, window.location.origin + window.location.pathname + \"?\" + url);\n }\n\n renderGrid(data, savedOptions = null) {\n this.setColumnDefinitionsAndRowData(data);\n this.toggleMergeEntitiesToggle(savedOptions);\n\n this.collapseFullyUncodedRows();\n\n this.gridApi.setGridOption(\"loading\", false);\n }\n\n loadValuesToInputs(values) {\n loadDateInputs(values, this);\n\n const dateValue = values.date_range;\n if (dateValue === \"since_inception\") {\n this.startDateTarget.disabled = true;\n } else {\n this.startDateTarget.disabled = false;\n }\n\n if (this.hasIntervalSelectTarget) this.intervalSelectTarget.value = values.interval;\n if (this.hasConsolidationFormatSelectTarget)\n this.consolidationFormatSelectTarget.value = values.consolidation_format;\n if (this.hasCompareableTarget) this.compareableTarget.value = values.comparable;\n if (this.hasCompareToLastPeriodTarget) this.compareToLastPeriodTarget.checked = values.compare_to_last_period;\n\n setSelectValues(this.ledgersTarget, values.ledger_ids.map(Number));\n\n // Account codes and tags are loaded asynchronously. Check loadAsyncInputs() and comments on\n // loadGridData() for more info\n setOptionsCheckboxValue(this.optionTargets, \"show_zero_balance_accounts\", values.show_zero_balance_accounts);\n setOptionsCheckboxValue(this.optionTargets, \"show_inactive_accounts\", values.show_inactive_accounts);\n setOptionsCheckboxValue(this.optionTargets, \"show_consolidated_breakdown\", values.show_consolidated_breakdown);\n setOptionsCheckboxValue(\n this.optionTargets,\n \"show_lookthrough_consolidation\",\n values.show_lookthrough_consolidation,\n );\n setOptionsCheckboxValue(this.optionTargets, \"hide_account_categories\", values.hide_account_categories);\n setOptionsCheckboxValue(this.optionTargets, \"merge_entities\", values.merge_entities);\n }\n\n loadAsyncInputs() {\n const sessionReportOptions = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n\n if (\n sessionReportOptions &&\n sessionReportOptions.account_code_ids &&\n (sessionReportOptions.tag_ids || sessionReportOptions.col_tag_ids)\n ) {\n setOptionsCheckboxValue(\n this.optionTargets,\n \"group_by_account_codes\",\n sessionReportOptions.group_by_account_codes,\n );\n setOptionsCheckboxValue(this.optionTargets, \"group_by_tags\", sessionReportOptions.group_by_tags);\n\n setCheckboxValues(this.accountCodeTargets, sessionReportOptions.account_code_ids.map(Number));\n if (sessionReportOptions.row_tag_ids && this.hasRowTagsButtonTarget) {\n // If we have row tags, we want to select the row tags button so that they are shown\n this.rowTagsButtonTarget.click();\n setCheckboxValues(this.rowTagTargets, sessionReportOptions.row_tag_ids.map(Number));\n }\n\n let colTagIds = [];\n if (sessionReportOptions.col_tag_ids) {\n colTagIds = sessionReportOptions.col_tag_ids;\n } else if (sessionReportOptions.tag_ids) {\n colTagIds = sessionReportOptions.tag_ids;\n }\n\n setCheckboxValues(this.colTagTargets, colTagIds.map(Number));\n }\n\n this.asyncInputsLoadedValue = true;\n this.dispatch(\"report-inputs-loaded\");\n }\n\n exportReport(event: Event) {\n event.preventDefault();\n\n const reportType: ReportType = this.hasReportTypeValue ? (this.reportTypeValue as ReportType) : \"sumit-report\";\n const reportDate = new Date();\n\n const fileName = `${reportType}-${reportDate.toISOString().replace(/:/g, \"-\")}.xlsx`;\n\n const { showZeroBalanceAccountsValue, showInactiveAccountsValue } = this.getTogglesValues();\n const reportOptions: ReportOption[] = [\n { label: \"Showing zero balance accounts\", value: showZeroBalanceAccountsValue },\n { label: \"Includes inactive accounts\", value: showInactiveAccountsValue },\n ];\n\n this.gridApi.exportDataAsExcel({\n prependContent: headerRows(\n reportType,\n reportDate,\n this.startDateTarget.value,\n this.endDateTarget.value,\n this.getSelectedLedgerNames(),\n reportOptions,\n ),\n fileName,\n author: \"SumIt Software, Inc.\",\n sheetName: reportType,\n rowGroupExpandState: \"match\",\n headerRowHeight: this.consolidatedReport() ? 100 : 30,\n shouldRowBeSkipped: function (params) {\n return !params.node.displayed;\n },\n ...defaultExportParams,\n });\n }\n\n collapseFullyUncodedRows(): void {\n this.gridApi.forEachNode((rowNode) => {\n const childrenAfterGroup = rowNode.childrenAfterGroup;\n\n if (childrenAfterGroup?.length == 1 && childrenAfterGroup[0].key == \"Uncoded\") {\n rowNode.setExpanded(false);\n }\n });\n }\n\n getReportOptions(): object {\n const options = JSON.parse(sessionStorage.getItem(this.sessionStorageKey(\"report_options\")));\n options[\"ag_grid_state\"] = this.gridApi.getState();\n\n return options;\n }\n\n async saveReportTemplate(e: Event) {\n e.preventDefault();\n\n const reportTemplateData = {\n report_type: this.saveReportTypeTarget.value,\n report_options: prepareDateRangeOptions(this.getReportOptions()),\n };\n\n await saveReportTemplate(reportTemplateData, this.saveReportTypeTarget.value, this.saveReportNameTarget.value);\n }\n\n updateSavedReportTemplate() {\n const reportTemplateData = {\n report_type: this.saveReportTypeTarget.value,\n report_options: prepareDateRangeOptions(this.getReportOptions()),\n };\n\n updateSavedReportTemplate(reportTemplateData, this.reportTemplateIdValue);\n }\n\n getOptionsObject() {\n const options = {};\n this.optionTargets.forEach((option) => {\n options[option.name] = option.checked;\n });\n return options;\n }\n\n setColumnDefinitionsAndRowData(data) {\n setDateAndAlertDisplay(this, data);\n\n const cellRenderer =\n hasOption(this, \"hide_account_categories\") && getOptionState(this, \"hide_account_categories\")\n ? \"flattenedAccountCellRenderer\"\n : \"accountCellRenderer\";\n\n this.gridApi.updateGridOptions({\n columnDefs: this.createColumnDefinitions(data.column_definitions, 0, data.report_summary.include_col_tags),\n autoGroupColumnDef: {\n ...this.accountGroupColumnDefinition,\n cellRendererParams: {\n suppressCount: true,\n innerRenderer: cellRenderer,\n },\n },\n });\n\n const originalRowData = this.gridApi.getGridOption(\"rowData\") || [];\n\n // this is needed in order for the ag grid report state filters to be applied properly. It doesn't work\n // if the row_data is loaded using updateGridOptions(). The filters will show up but won't actually filter the data.\n this.gridApi.setGridOption(\"rowData\", data.row_data);\n\n if (!this.gridOptions.initialState) {\n this.autoSizeColumns();\n }\n\n // Detect if the breadcrumbs on the rows have changed - if they have, we expand all the rows.\n // originalRowData would be empty if the report is being loaded for the first time, in which case we don't\n // want to expand all the rows\n if (originalRowData.length > 0 && shouldRefreshGrouping(originalRowData, data.row_data)) {\n this.gridApi.expandAll();\n }\n\n if (this.hasExportButtonTarget) {\n this.exportButtonTarget.disabled = false;\n }\n if (this.hasSaveReportButtonTarget) {\n this.saveReportButtonTarget.disabled = false;\n }\n if (this.hasUpdateReportButtonTarget) {\n if (this.reportTemplateIdValue) {\n this.updateReportButtonTarget.classList.remove(\"hidden\");\n } else {\n this.updateReportButtonTarget.classList.add(\"hidden\");\n }\n }\n }\n\n reportDateHeader() {\n const reportTypes = [\"balance_sheet\", \"trial_balance\", \"consolidated\", \"net_worth\"];\n\n if (reportTypes.includes(this.reportTypeValue)) {\n return `As of ${formatDateForDisplay(this.endDateTarget.value)}`;\n } else if (this.startDateTarget.value === \"\" && this.endDateTarget.value) {\n return \"Since Inception\";\n } else {\n return `For the period ${formatDateForDisplay(this.startDateTarget.value)} - ${formatDateForDisplay(\n this.endDateTarget.value,\n )}`;\n }\n }\n\n mergeEntitiesToggleTargetConnected() {\n this.toggleMergeEntitiesToggle();\n }\n\n toggleMergeEntitiesToggle(savedOptions = null) {\n if (!this.hasMergeEntitiesToggleTarget) {\n return;\n }\n\n const ledgerSelectValues = getSelectValues(this.ledgersTarget);\n const label = this.mergeEntitiesToggleTarget.parentElement.previousElementSibling;\n const container = label.parentElement;\n const toggle = label.nextElementSibling;\n\n if (ledgerSelectValues.length !== 1) {\n this.mergeEntitiesToggleTarget.disabled = false;\n label.classList.add(\"text-sumit-primary-black\");\n label.classList.remove(\"text-gray-300\");\n container.classList.add(\"hover:bg-gray-200\");\n toggle.classList.remove(\"pointer-events-none\");\n if (!toggle.classList.contains(\"cursor-pointer\")) {\n toggle.classList.add(\"cursor-pointer\");\n }\n this.toggleCompareToLastPeriodButton(this.mergeEntitiesToggleTarget.checked, savedOptions);\n } else {\n this.mergeEntitiesToggleTarget.checked = false;\n this.mergeEntitiesToggleTarget.disabled = true;\n label.classList.remove(\"text-sumit-primary-black\");\n label.classList.add(\"text-gray-300\");\n container.classList.remove(\"hover:bg-gray-200\");\n toggle.classList.remove(\"cursor-pointer\");\n toggle.classList.add(\"pointer-events-none\");\n this.toggleCompareToLastPeriodButton(true, savedOptions);\n }\n }\n\n toggleCompareToLastPeriodButton(enabled, savedOptions = null) {\n if (enabled) {\n this.compareToLastPeriodTarget.disabled = false;\n if (savedOptions?.compare_to_last_period) {\n this.compareToLastPeriodTarget.checked = true;\n }\n this.compareToLastPeriodTarget.parentElement.parentElement\n .querySelector(\"[data-compare-to-last-period-button-target='info']\")\n .classList.add(\"hidden\");\n this.compareToLastPeriodTarget.parentElement\n .querySelector(\"[data-compare-to-last-period-button-target='text']\")\n .classList.remove(\"text-gray-400\");\n } else {\n this.compareToLastPeriodTarget.disabled = true;\n this.compareToLastPeriodTarget.checked = false;\n this.compareToLastPeriodTarget.parentElement.parentElement\n .querySelector(\"[data-compare-to-last-period-button-target='info']\")\n .classList.remove(\"hidden\");\n this.compareToLastPeriodTarget.parentElement\n .querySelector(\"[data-compare-to-last-period-button-target='text']\")\n .classList.add(\"text-gray-400\");\n }\n }\n\n createColumnDefinitions(columnDefData: ServerProvidedColDef[], childrenLevel = 0, isColTaggedReport = false) {\n const columnDefs: ServerProvidedColDef[] = [];\n\n columnDefData.forEach((columnDef) => {\n // If this is a column tagged report but the column has no children defined, then we are combining entities\n if (isColTaggedReport && columnDef.children === undefined && childrenLevel === 0 && columnDef.field !== \"total\") {\n columnDef.headerClass = \"bg-gray-200 ag-sub-header-cell\";\n columnDef.headerGroupComponent = HeaderGroupRenderer;\n columnDef.headerComponentParams = {\n template: tagHeaderTemplate(columnDef, false),\n };\n }\n if (isColTaggedReport && childrenLevel > 0) {\n columnDef.headerClass = \"bg-gray-200 ag-sub-header-cell\";\n columnDef.headerGroupComponent = HeaderGroupRenderer;\n columnDef.headerComponentParams = {\n template: tagHeaderTemplate(columnDef, childrenLevel > 1),\n };\n }\n if (this.consolidatedReport() && columnDef?.metadata?.consolidationMetadata) {\n columnDef.headerComponentParams = {\n template: consolidatedHeaderTemplate(columnDef),\n };\n }\n\n if (columnDef.includeInTotal) {\n this.totalCols.add(columnDef.field);\n }\n\n columnDef.cellClass = getClassesForCells;\n columnDef.cellRenderer = NumberCellRenderer;\n\n if (columnDef.field === \"percent_change_total\") {\n columnDef.valueGetter = this.percentChangeTotalValueGetter;\n // for total rows the valueFormatter from the dataTypeDefinitions won't work as the rows have already been formatted.\n // Check the note at the end of this paragraph: https://www.ag-grid.com/javascript-data-grid/cell-data-types/#pre-defined-cell-data-types\n columnDef.valueFormatter = dataTypeDefinitions.percentage.valueFormatter;\n } else {\n columnDef.valueGetter = numberValueGetter;\n }\n\n if (columnDef.children != null) {\n columnDef.children = this.createColumnDefinitions(columnDef.children, childrenLevel + 1, isColTaggedReport);\n }\n\n if (columnDef.field === \"total\") {\n const totalCol = {\n headerName: \"Total\",\n colId: \"total\",\n aggFunc: \"sum\",\n resizable: false,\n minWidth: 150,\n maxWidth: 200,\n cellRenderer: NumberCellRenderer,\n cellDataType: \"number\",\n cellClass: getClassesForCells,\n valueGetter: this.totalValueGetter,\n };\n\n columnDefs.push({\n ...totalCol,\n });\n } else {\n delete columnDef.includeInTotal;\n columnDef.context = {\n metadata: columnDef.metadata,\n };\n delete columnDef.metadata;\n\n columnDefs.push({\n ...columnDef,\n });\n }\n });\n\n return columnDefs;\n }\n\n autoSizeColumns() {\n this.gridApi.sizeColumnsToFit();\n }\n\n aggPercentChangeTotal = (params: IAggFuncParams) => {\n let currentPeriodTotal = 0;\n let priorPeriodTotal = 0;\n\n params.values.forEach((value) => {\n if (!isNaN(value.prior_period_total)) {\n priorPeriodTotal += parseFloat(value.prior_period_total);\n }\n\n if (!isNaN(value.current_period_total)) {\n currentPeriodTotal += parseFloat(value.current_period_total);\n }\n });\n\n const changeTotal = currentPeriodTotal - priorPeriodTotal;\n const percentChangeTotal = calculatePercentChangeTotal({ priorPeriodTotal, changeTotal });\n\n return {\n prior_period_total: priorPeriodTotal,\n current_period_total: currentPeriodTotal,\n change_total: changeTotal,\n toString: () => percentChangeTotal,\n };\n };\n\n percentChangeTotalValueGetter = (params: ValueGetterParams) => {\n // no need to handle group levels - calculated in the \"aggPercentChangeTotal\" aggFunc\n if (!params.node.group) {\n const percentChangeTotal = calculatePercentChangeTotal({\n priorPeriodTotal: params.data.prior_period_total,\n changeTotal: params.data.change_total,\n });\n\n return {\n prior_period_total: params.data.prior_period_total,\n current_period_total: params.data.current_period_total,\n change_total: parseFloat(params.data.change_total),\n toString: () => percentChangeTotal,\n };\n }\n };\n\n totalValueGetter = (params: ValueGetterParams) => {\n const node = params.node as unknown as RowNode;\n\n // Don't want to display anything for group headers, the totals are handled in the footer.\n if (isGroupHeader(node)) {\n return null;\n } else {\n const cols = Array.from(this.totalCols);\n\n return aggColumnValues(params, cols);\n }\n };\n\n accountComparator(valueA: string, valueB: string, nodeA: RowNode, nodeB: RowNode, _isInverted: boolean): number {\n const accountOrder = [\n \"Assets\",\n \"Liabilities And Equity\",\n \"Liabilities\",\n \"Equities\",\n \"Revenues\",\n \"Expenses\",\n \"Net Income\",\n \"Initial Balance\",\n \"Sources of Cash\",\n \"Uses of Cash\",\n \"Ending Balance\",\n \"Total Net Worth\",\n ];\n const nodeAAccountNumberAndName = nodeA?.data?.accountNumberAndName;\n const nodeBAccountNumberAndName = nodeB?.data?.accountNumberAndName;\n\n // If this is a top-level account, organize by account order\n if (\n typeof valueA === \"string\" &&\n typeof valueB === \"string\" &&\n accountOrder.indexOf(valueA.split(\" - \").at(-1)) != -1 &&\n accountOrder.indexOf(valueB.split(\" - \").at(-1)) != -1\n ) {\n return accountOrder.indexOf(valueB.split(\" - \").at(-1)) - accountOrder.indexOf(valueA.split(\" - \").at(-1));\n } else if (\n nodeAAccountNumberAndName &&\n nodeBAccountNumberAndName &&\n accountOrder.indexOf(nodeAAccountNumberAndName.split(\" - \").at(-1)) != -1 &&\n accountOrder.indexOf(nodeBAccountNumberAndName.split(\" - \").at(-1)) != -1\n ) {\n return (\n accountOrder.indexOf(nodeBAccountNumberAndName.split(\" - \").at(-1)) -\n accountOrder.indexOf(nodeAAccountNumberAndName.split(\" - \").at(-1))\n );\n } else if (nodeAAccountNumberAndName && nodeBAccountNumberAndName) {\n // If this is a child account, order by account number and name\n return nodeBAccountNumberAndName.toString().localeCompare(nodeAAccountNumberAndName.toString());\n } else if (typeof valueA === \"string\" && typeof valueB === \"string\") {\n // Otherwise order alphabetically\n return valueB.toString().localeCompare(valueA.toString());\n } else {\n return 0;\n }\n }\n\n validateEntitySetIfConsolidatedReport() {\n if (this.consolidatedReport()) {\n return validateEntitySet(this);\n } else {\n return true;\n }\n }\n\n getTogglesValues() {\n const showZeroBalanceAccountsCheckbox = document.querySelector(\"#show_zero_balance_accounts\") as HTMLInputElement;\n const showInactiveAccountsCheckbox = document.querySelector(\"#show_inactive_accounts\") as HTMLInputElement;\n\n const showZeroBalanceAccountsValue = showZeroBalanceAccountsCheckbox?.checked;\n const showInactiveAccountsValue = showInactiveAccountsCheckbox?.checked;\n\n return { showZeroBalanceAccountsValue, showInactiveAccountsValue };\n }\n\n get accountGroupColumnDefinition() {\n return {\n headerName: \"Account\",\n minWidth: 300,\n flex: 1,\n pinned: \"left\" as ColumnPinnedType,\n cellClass: getClassesForAccounts,\n cellRendererSelector: (_params) => {\n return { component: \"agGroupCellRenderer\" };\n },\n cellRendererParams: {\n suppressCount: true,\n innerRenderer: \"accountCellRenderer\",\n },\n sort: \"desc\" as SortDirection,\n comparator: this.accountComparator,\n } as ColDef;\n }\n\n getSelectedLedgerNames() {\n return getSelectValues(this.ledgersTarget).map(\n (id) => (this.ledgersTarget.querySelector(`option[value=\"${id}\"]`) as HTMLOptionElement).innerText,\n );\n }\n\n consolidatedReport() {\n return [\"consolidated\", \"net_worth\"].includes(this.reportTypeValue);\n }\n\n sessionStorageKey(type: string) {\n return `reporting_${this.reportTypeValue}_report:${type}`;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\nimport { parseDateRangeOption } from \"../helpers/date_range_option_parser\";\n\n// Connects to data-controller=\"reporting-datepicker\"\nexport default class extends Controller {\n declare dateRangeTarget: TomInput;\n declare startDateTarget: HTMLInputElement;\n declare endDateTarget: HTMLInputElement;\n declare compareableTarget: HTMLInputElement;\n\n static targets = [\"dateRange\", \"startDate\", \"endDate\", \"compareable\"];\n\n clearDateRange() {\n this.dateRangeTarget.tomselect.clear();\n }\n\n clearStartAndEndDates() {\n this.startDateTarget.value = null;\n this.endDateTarget.value = null;\n this.startDateTarget.disabled = false;\n }\n\n input({ target: { value } }) {\n if (!value) {\n return;\n } else {\n const { startDate, endDate, comparable } = parseDateRangeOption(value);\n\n if (value === \"since_inception\") {\n this.startDateTarget.disabled = true;\n } else {\n this.startDateTarget.disabled = false;\n }\n\n this.startDateTarget.valueAsDate = startDate;\n this.endDateTarget.valueAsDate = endDate;\n this.compareableTarget.value = comparable;\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"reporting-row-options\"\nexport default class extends Controller {\n static targets = [\"tagsButton\", \"accountCodesButton\", \"tagsPanel\", \"accountCodesPanel\"];\n\n declare tagsButtonTarget: HTMLButtonElement;\n declare accountCodesButtonTarget: HTMLButtonElement;\n declare tagsPanelTarget: HTMLDivElement;\n declare accountCodesPanelTarget: HTMLDivElement;\n\n static values = {\n visiblePanel: {\n type: String,\n default: \"accountCodes\",\n }\n }\n\n declare visiblePanelValue: string;\n\n connect() {\n // Ensure the panel is set to the default value when connected\n this.visiblePanelValueChanged(this.visiblePanelValue);\n }\n\n togglePanel(event) {\n this.visiblePanelValue = event.params.panel\n }\n\n visiblePanelValueChanged(newValue: string) {\n if (newValue === \"accountCodes\") {\n this.showAccountCodes();\n } else if (newValue === \"tags\") {\n this.showTags();\n }\n }\n\n showTags() {\n this.resetCheckboxes(this.accountCodesPanelTarget);\n this.updateButtonStyles(this.tagsButtonTarget, this.accountCodesButtonTarget);\n this.togglePanels(this.tagsPanelTarget, this.accountCodesPanelTarget);\n }\n\n showAccountCodes() {\n this.resetCheckboxes(this.tagsPanelTarget);\n this.updateButtonStyles(this.accountCodesButtonTarget, this.tagsButtonTarget);\n this.togglePanels(this.accountCodesPanelTarget, this.tagsPanelTarget);\n }\n\n resetCheckboxes(panel: HTMLElement) {\n const checkboxes = panel.querySelectorAll(\"input[type='checkbox']\");\n checkboxes.forEach((checkbox: HTMLInputElement) => { checkbox.checked = false; });\n }\n\n updateButtonStyles(activeButton: HTMLButtonElement, inactiveButton: HTMLButtonElement) {\n inactiveButton.classList.remove(\"bg-cyan-600\", \"text-white\");\n inactiveButton.classList.add(\"bg-white\", \"text-black\", \"btn-white\");\n\n activeButton.classList.remove(\"bg-white\", \"text-black\", \"btn-white\");\n activeButton.classList.add(\"bg-cyan-600\", \"text-white\");\n }\n\n togglePanels(showPanel: HTMLElement, hidePanel: HTMLElement) {\n showPanel.classList.remove(\"hidden\");\n hidePanel.classList.add(\"hidden\");\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nimport { post } from \"@rails/request.js\";\n\ninterface ValuesTargets {\n min?: string;\n max?: string;\n value: string | string[];\n}\n\nexport default class extends Controller {\n static targets = [\n \"amountActive\",\n \"amountOperator\",\n \"amountValue\",\n \"amountRangeStart\",\n \"amountRangeEnd\",\n \"descriptionActive\",\n \"descriptionOperator\",\n \"descriptionValue\",\n \"dateActive\",\n \"dateOperator\",\n \"dateValue\",\n \"dateRangeStart\",\n \"dateRangeEnd\",\n \"ledgerIdActive\",\n \"ledgerIdOperator\",\n \"ledgerIdValue\",\n \"accountTemplateIdActive\",\n \"accountTemplateIdOperator\",\n \"accountTemplateIdValue\",\n \"previewButton\"\n ];\n\n declare amountActiveTarget: HTMLInputElement;\n declare amountOperatorTarget: HTMLSelectElement;\n declare amountValueTarget: HTMLInputElement;\n declare amountRangeStartTarget: HTMLInputElement;\n declare amountRangeEndTarget: HTMLInputElement;\n\n declare descriptionOperatorTargets: HTMLSelectElement[];\n declare descriptionValueTargets: HTMLInputElement[];\n\n declare dateActiveTarget: HTMLInputElement;\n declare dateOperatorTarget: HTMLSelectElement;\n declare dateValueTarget: HTMLInputElement;\n declare dateRangeStartTarget: HTMLInputElement;\n declare dateRangeEndTarget: HTMLInputElement;\n\n declare ledgerIdValueTarget: HTMLSelectElement;\n\n declare accountTemplateIdValueTarget: HTMLSelectElement;\n\n declare previewButtonTarget: HTMLButtonElement;\n declare hasPreviewButtonTarget: boolean;\n\n getPreview() {\n if (this.hasPreviewButtonTarget) {\n this.previewButtonTarget.disabled = true;\n }\n\n post(\n '/account_reconciliation/rules/rule_preview', \n {\n body: this.buildConditions(),\n responseKind: \"turbo-stream\",\n }\n );\n }\n\n buildConditions() {\n let conditions = [];\n\n let condition = this.getCondition(\"amount\", this.amountOperatorTarget.value, {min: this.amountRangeStartTarget.value, max: this.amountRangeEndTarget.value, value: this.amountValueTarget.value});\n if (this.amountActiveTarget.checked && condition) {\n conditions.push(condition)\n }\n\n this.descriptionOperatorTargets.forEach((descriptionOperatorTarget, index) => {\n condition = this.getCondition(\"description\", descriptionOperatorTarget.value, {value: this.descriptionValueTargets[index].value});\n if (condition) {\n conditions.push(condition);\n }\n });\n\n condition = this.getCondition(\"date\", this.dateOperatorTarget.value, {min: this.dateRangeStartTarget.value, max: this.dateRangeEndTarget.value, value: this.dateValueTarget.value});\n if (this.dateActiveTarget.checked) {\n conditions.push(condition)\n }\n\n const ledgerSelectedOptions = Array.from(this.ledgerIdValueTarget.selectedOptions).map((option) => option.value);\n if (ledgerSelectedOptions.length > 0) {\n conditions.push(this.getCondition(\"ledger_ids\", null, {value: ledgerSelectedOptions}));\n }\n\n const acccountSelectedOption = Array.from(this.accountTemplateIdValueTarget.selectedOptions).map((option) => option.value);\n if (acccountSelectedOption.length > 0) {\n conditions = conditions.concat(this.getCondition(\"account_template_ids\", null, {value: acccountSelectedOption}));\n }\n return {\n rule: {\n conditions_attributes: conditions\n }\n }\n }\n\n getCondition(field, conditionTargetValue, valuesTargets: ValuesTargets) {\n if (this.noValuesForCondition(valuesTargets)) {\n return null;\n }\n\n if (!conditionTargetValue) {\n return {\n type: field,\n operator: \"include\",\n value: valuesTargets.value\n }\n } else if (conditionTargetValue === \"between\") {\n return {\n type: field,\n operator: conditionTargetValue,\n range_start: valuesTargets.min,\n range_end: valuesTargets.max\n }\n } else {\n return {\n type: field,\n operator: conditionTargetValue,\n value: valuesTargets.value,\n }\n }\n }\n\n noValuesForCondition(valuesTargets: ValuesTargets) {\n return (!valuesTargets.value && !valuesTargets.min && !valuesTargets.max);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"gridSettingsInput\", \"periodInput\"];\n\n declare gridSettingsInputTarget: HTMLInputElement;\n declare hasGridSettingsInputTarget: boolean;\n declare periodInputTarget: HTMLInputElement;\n declare hasPeriodInputTarget: boolean;\n\n connect() {\n this.dispatch(\"connected\");\n }\n\n updateGridState(event) {\n if (this.hasGridSettingsInputTarget) {\n this.gridSettingsInputTarget.value = JSON.stringify(event.detail.gridState);\n }\n\n if (this.hasPeriodInputTarget) {\n this.periodInputTarget.value = event.detail.period;\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"savingMessage\", \"savingText\", \"savingMessageIcon\", \"successMessageIcon\"];\n declare savingMessageTarget: HTMLElement;\n declare savingTextTarget: HTMLElement;\n declare savingMessageIconTarget: HTMLElement;\n declare successMessageIconTarget: HTMLElement;\n\n handleTurboFinish(event) {\n if (event.detail.success) {\n this.showSuccessMessage();\n } else {\n this.showErrorMessage();\n }\n }\n\n showSavingMessage() {\n this.savingMessageTarget.classList.remove(\"hidden\");\n this.savingMessageIconTarget.classList.remove(\"hidden\");\n this.successMessageIconTarget.classList.add(\"hidden\");\n this.savingTextTarget.textContent = \"Saving...\";\n }\n\n hideSavingMessage() {\n this.savingMessageTarget.classList.add(\"hidden\");\n }\n\n showSuccessMessage() {\n this.savingMessageIconTarget.classList.add(\"hidden\");\n this.successMessageIconTarget.classList.remove(\"hidden\");\n this.savingTextTarget.textContent = \"Saved\";\n\n setTimeout(() => {\n this.hideSavingMessage();\n }, 2000); // Hide success message after 2 seconds\n }\n\n showErrorMessage() {\n this.savingTextTarget.textContent = \"Error Saving!\";\n setTimeout(() => {\n this.hideSavingMessage();\n }, 2000); // Hide error message after 2 seconds\n }\n} \n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"scroll-to\"\nexport default class extends Controller {\n static targets = [\"link\"];\n static values = {\n activeClass: {\n type: String,\n default: \"active\",\n },\n };\n\n declare readonly linkTargets: HTMLAnchorElement[];\n declare readonly hasLinkTarget: boolean;\n declare readonly activeClassValue: string;\n\n connect(): void {\n this.scrollTo(window.location.hash.replace(/^#/, \"\"));\n }\n\n handleClick(event: Event): void {\n event.preventDefault();\n\n const id: string = (event.target as HTMLAnchorElement).hash.replace(/^#/, \"\");\n\n this.scrollTo(id);\n }\n\n scrollTo(id: string): void {\n const target: HTMLElement = document.getElementById(id);\n\n if (!target) {\n console.warn(`[stimulus-scroll-to] The element with the id: \"${id}\" does not exist on the page.`);\n return;\n }\n\n // Replace the state to the browser's history stack\n history.replaceState(null, \"\", `#${id}`);\n\n target.scrollIntoView({ behavior: \"smooth\" });\n\n this.setActiveState();\n }\n\n setActiveState(): void {\n if (this.hasLinkTarget) {\n this.linkTargets.forEach((link: HTMLAnchorElement) => {\n const id: string = link.hash.replace(/^#/, \"\");\n\n if (id === window.location.hash.replace(/^#/, \"\")) {\n link.classList.add(this.activeClassValue);\n } else {\n link.classList.remove(this.activeClassValue);\n }\n });\n }\n }\n}\n","import CheckboxSelectAll from \"stimulus-checkbox-select-all\";\n\nexport default class extends CheckboxSelectAll {\n declare checkboxTargets: HTMLInputElement[];\n declare triggerInputEvent: (checkbox: HTMLInputElement) => void;\n\n toggle(e: Event): void {\n e.preventDefault()\n\n this.checkboxTargets.forEach(checkbox => {\n checkbox.indeterminate = false;\n // @ts-ignore\n checkbox.checked = e.target.checked\n this.triggerInputEvent(checkbox)\n })\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport TomSelect from \"tom-select\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\nexport default class extends Controller {\n declare select: TomSelect;\n\n static values = {\n classes: Array,\n itemClasses: { type: Array, default: [] },\n optgroupHeaderClasses: { type: Array, default: [\"optgroup-header\", \"font-semibold\", \"border-t\"] },\n wrapperClasses: { type: Array, default: [] },\n hidePlaceholder: { type: Boolean, default: false },\n variant: String,\n maxOptions: { type: Number, default: 100 },\n persist: { type: Boolean, default: true },\n plugins: { type: Array, default: [\"remove_button\"] },\n };\n\n declare classesValue: string[];\n declare hasClassesValue: boolean;\n declare itemClassesValue: string[];\n declare hasItemClassesValue: boolean;\n declare wrapperClassesValue: string[];\n declare hasWrapperClassesValue: boolean;\n declare hidePlaceholderValue: boolean;\n declare variantValue: string;\n declare maxOptionsValue: number;\n declare persistValue: boolean;\n declare pluginsValue: string[];\n declare optgroupHeaderClassesValue: string[];\n\n connect() {\n const options = {\n plugins: this.pluginsValue,\n maxOptions: this.maxOptionsValue,\n itemClass: `item ${this.itemClassesValue.join(\" \")}`,\n persist: this.persistValue,\n render: {\n optgroup_header: (data, escape) => {\n return `\n
\n ${escape(data.label)}\n
\n `;\n },\n },\n };\n\n // If we've set a placeholder from the select component we want to hide when options are selected\n // Do so with the hidePlaceholder option here\n if (this.hidePlaceholderValue) {\n options[\"hidePlaceholder\"] = true;\n }\n\n if (this.variantValue == \"withRadioOptions\") {\n options[\"render\"][\"option\"] = (data, escape) => {\n const checked = this.select.items.includes(data.value) ? \"checked\" : \"\";\n return `\n
\n \n ${escape(data.text)}\n
\n `;\n };\n\n options[\"onChange\"] = () => {\n Object.keys(this.select.options).forEach((key) => {\n const hasTomSelectRendered = this.select.options[key].$div !== undefined;\n if (!hasTomSelectRendered) {\n return;\n }\n\n const radio = this.select.options[key].$div.children[0] as HTMLInputElement;\n\n if (this.select.items.includes(key)) {\n radio.checked = true;\n } else {\n radio.checked = false;\n }\n });\n };\n\n options[\"onDelete\"] = () => {\n this.dispatch(\"onDelete\");\n return true;\n };\n }\n\n this.select = new TomSelect(this.element, options);\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n if (className != \"\") {\n this.select.control.classList.add(className);\n }\n });\n }\n\n if (this.hasWrapperClassesValue) {\n this.wrapperClassesValue.forEach((className) => {\n if (className != \"\") {\n this.select.wrapper.classList.add(className);\n }\n });\n }\n }\n\n resetSelect() {\n this.select.clear();\n }\n\n unfocusSelect() {\n this.select.blur();\n }\n\n disconnect() {\n this.select.destroy();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"select-toggle\"\nexport default class extends Controller {\n static targets = [\"section\", \"source\"];\n\n declare sourceTarget: HTMLSelectElement;\n declare sectionTargets: HTMLDivElement[];\n\n connect() {\n const startingValue = this.sourceTarget.value;\n\n this.toggleVisibility(startingValue);\n }\n\n handleChange(event) {\n const selectedValue = event.target.value;\n\n this.toggleVisibility(selectedValue);\n }\n\n toggleVisibility(value: string) {\n if (value === \"\") {\n return;\n }\n\n this.sectionTargets.forEach((section) => {\n const showWhens = section.dataset.showWhen.split(\",\").map((showWhen) => showWhen.trim());\n\n showWhens.forEach(() => {\n if (this.willDisplaySection(value, showWhens)) {\n section.classList.remove(\"hidden\");\n } else {\n section.classList.add(\"hidden\");\n }\n });\n });\n }\n\n willDisplaySection(value: string, showWhens: string[]) {\n return value !== \"\" && showWhens.includes(value);\n }\n}\n","// This controller is used to manage the content of multiple slideovers\n// at the same time. On show, it will show the content with the id\n// of the correct contents in a slideover and dispatch a show event.\n// The slideover controller listens for this event and will open the\n// slideover.\n\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"content\", \"overlay\"];\n\n declare contentTargets: HTMLElement[];\n declare overlayTarget: HTMLElement;\n\n handleShow(event) {\n const contentId = event.params.id || event.detail.id;\n this.contentTargets.forEach((target) => {\n if (target.id == contentId) {\n history.replaceState(null, \"\", \"#\");\n target.classList.remove(\"hidden\");\n } else {\n target.classList.add(\"hidden\");\n }\n });\n if (event.params.unhideableOverlay) {\n this.overlayTarget.dataset.action = \"\";\n } else {\n this.overlayTarget.dataset.action = \"click->slideover#toggle\";\n }\n\n this.dispatch(\"show\");\n }\n\n handleHide() {\n history.replaceState(null, \"\", \"#\");\n }\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static targets = [\"menu\"]\n declare menuTarget: HTMLElement\n\n toggle(event: Event) {\n event.stopPropagation();\n this.menuTarget.classList.toggle(\"hidden\");\n }\n\n hide(event: Event) {\n // Don't hide if clicking inside the dropdown menu\n if (this.menuTarget.contains(event.target as Node)) {\n return;\n }\n\n // Hide if clicking outside the dropdown menu\n this.menuTarget.classList.add(\"hidden\");\n }\n\n forceHide() {\n this.menuTarget.classList.add(\"hidden\");\n }\n}","// This controller is used to compute and set the left/right positions \n// of all the sticky table-cells. \n// These positions are the cumulative value of the cells siblings, \n// which can change depending on the width of siblings or if the user changes the window size.\n// This also hides the shadow over the non-sticky cells when there is no scroll\n\nimport { Controller } from \"@hotwired/stimulus\";\nexport default class extends Controller {\n static targets = [\"container\", \"leftColumn\", \"rightColumn\", \"leftShadow\", \"rightShadow\"];\n\n declare containerTarget: HTMLElement;\n declare leftColumnTargets: HTMLElement[];\n declare rightColumnTargets: HTMLElement[];\n declare leftShadowTarget: HTMLElement;\n declare rightShadowTarget: HTMLElement;\n\n declare columnPositions: object;\n declare shadowPositions: object;\n\n declare Z_INDEX_PLANE_FOR_TABLE: number;\n\n connect() {\n this.Z_INDEX_PLANE_FOR_TABLE = 30;\n this.columnPositions = {\n left: [],\n right: []\n };\n\n this.shadowPositions = {\n left: 0,\n right: 0,\n }\n\n for ( const direction of [\"left\", \"right\"] ) {\n this.calculateStickyColumnPositions(direction);\n this.setStickyColumnPosition(direction);\n this[`${direction}ShadowTarget`].style.zIndex = this.Z_INDEX_PLANE_FOR_TABLE + 1;\n }\n\n // this.maybeHideShadowDivs();\n }\n\n updateShadows() {\n for ( const direction of [\"left\", \"right\"] ) {\n this.calculateStickyColumnPositions(direction);\n this.setShadowPosition(direction);\n }\n\n // this.maybeHideShadowDivs();\n }\n\n maybeHideShadowDivs() {\n if ( this.isOverflowing() ) {\n this.leftShadowTarget.classList.remove('invisible');\n this.rightShadowTarget.classList.remove('invisible');\n } else {\n this.leftShadowTarget.classList.add('invisible');\n this.rightShadowTarget.classList.add('invisible');\n }\n }\n\n calculateStickyColumnPositions(direction) {\n const columnTargets = direction == \"left\" ? this.leftColumnTargets : this.rightColumnTargets.reverse();\n\n for ( const [index, col] of columnTargets.entries() ) {\n const isFirstColumn = index === 0\n if ( isFirstColumn ) { this.columnPositions[direction].push(0); }\n\n const cumulativeWidth = this.columnPositions[direction][index] + col.offsetWidth;\n\n const isLastColumn = index === columnTargets.length - 1\n\n if ( ! isLastColumn ) { \n this.columnPositions[direction].push(cumulativeWidth);\n } else {\n this.shadowPositions[direction] = cumulativeWidth;\n continue;\n }\n }\n }\n\n setStickyColumnPosition(direction) {\n const rows = this.element.querySelectorAll(\".table-row\");\n\n for ( const [positionIndex, absolutePosition] of this.columnPositions[direction].entries() ) {\n rows.forEach( (row, rowIndex) => { \n const cells = row.querySelectorAll(\".table-cell\");\n\n const positionIndexFromRight = cells.length - 1 - positionIndex;\n const cellIndex = direction == \"left\" ? positionIndex : positionIndexFromRight;\n\n const cell = cells[cellIndex];\n cell.classList.add(\"sticky\", \"bg-white\");\n cell.style[direction] = `${absolutePosition}px`;\n cell.style.zIndex = `${this.Z_INDEX_PLANE_FOR_TABLE - rowIndex}`;\n });\n }\n\n this.setShadowPosition(direction);\n }\n\n setShadowPosition(direction) {\n this[`${direction}ShadowTarget`].style[direction] = `${this.shadowPositions[direction]}px`;\n }\n\n isOverflowing() {\n return this.containerTarget.scrollWidth > this.containerTarget.clientWidth\n }\n}","// Example usage:\n//
\n\nimport { Controller } from \"@hotwired/stimulus\";\nimport tippy, { Instance as TippyInstance } from \"tippy.js\";\nimport \"tippy.js/themes/light.css\";\n\nexport default class extends Controller {\n static targets = [\"button\"];\n\n static values = {\n content: String,\n theme: String,\n allowHtml: Boolean,\n maxWidth: Number,\n };\n\n declare tippy: TippyInstance;\n declare hasContentValue: boolean;\n declare themeValue: string;\n declare hasThemeValue: boolean;\n declare allowHtmlValue: boolean;\n declare hasAllowHtmlValue: boolean;\n declare contentValue: string | undefined;\n declare hasMaxWidthValue: boolean;\n declare maxWidthValue: number | undefined;\n declare hasButtonTarget: boolean;\n declare buttonTarget: HTMLButtonElement | undefined;\n\n connect() {\n const options = {};\n\n if (this.hasContentValue) {\n options[\"content\"] = this.contentValue;\n }\n\n if (this.hasThemeValue) {\n options[\"theme\"] = this.themeValue;\n }\n\n if (this.hasMaxWidthValue) {\n options[\"maxWidth\"] = this.maxWidthValue;\n }\n\n if (this.hasAllowHtmlValue) {\n options[\"allowHTML\"] = this.allowHtmlValue;\n }\n\n options[\"onCreate\"] = (instance) => {\n const tooltip = instance.popper.querySelector('.tippy-content');\n if (tooltip) {\n tooltip.style.fontSize = (this.element as HTMLElement).dataset.tippyFontSize || \"inherit\";\n }\n }\n\n if (this.hasButtonTarget) {\n this.tippy = tippy(this.buttonTarget, options);\n } else {\n this.tippy = tippy(this.element, options);\n }\n }\n\n handleToggleEvent(event) {\n const enabled = event.detail.enabled;\n\n if (enabled) {\n this.enable();\n } else {\n this.disable();\n }\n }\n\n show() {\n this.tippy.show();\n }\n\n hide() {\n this.tippy.hide();\n }\n\n disable() {\n this.tippy.disable();\n }\n\n enable() {\n this.tippy.enable();\n }\n\n disconnect() {\n this.tippy.destroy();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"submit\"\nexport default class extends Controller {\n static values = {\n frameId: String,\n };\n\n declare hasFrameIdValue: boolean;\n declare frameIdValue: string | undefined;\n\n submit() {\n this.element.requestSubmit();\n }\n\n submitForm() {\n this.element.form.requestSubmit();\n }\n\n checkResponse(event) {\n if (event.detail.success) {\n this.dispatch(\"success\");\n }\n }\n\n checkResponseAndRedirect(event) {\n const response = event.detail.fetchResponse.response;\n\n if (response.ok) {\n const redirectUrl = response.url;\n\n if (redirectUrl) {\n window.location.href = redirectUrl;\n }\n }\n }\n\n // This is used to prevent flashing an error message on form submit when the user is redirected\n // Since the redirect response is not a Turbo frame, the frame-missing event is fired, so we just hide the frame\n hideFrame() {\n document.getElementById(this.frameIdValue).hidden = true;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\n\n// Connects to data-controller=\"subtype-dropdown\"\nexport default class extends Controller {\n static targets = [\"subtypeSelect\", \"typeSelect\"];\n\n static values = {\n url: String,\n };\n\n declare subtypeSelectTargets: HTMLSelectElement[];\n declare typeSelectTarget: HTMLSelectElement;\n declare urlValue: string;\n\n typeChanged(_event: Event) {\n this.subtypeSelectTargets.forEach((selectTarget: HTMLSelectElement) => {\n this.getSelectTargetTurboFrame(selectTarget);\n });\n }\n\n // Use turbo streams to update the subtype dropdown. This action disables the drop down to start. The\n // turbo stream response returns a drop down that is enabled and has the correct options (which is why we\n // don't disable it in this function)\n getSelectTargetTurboFrame(element: HTMLSelectElement) {\n element.disabled = true;\n\n const selectedType = this.typeSelectTarget.selectedOptions[0].value;\n const selectedSubtype = element.hasChildNodes() ? element.selectedOptions[0].value : \"\";\n\n if (selectedType === \"\") {\n element.innerHTML = \"\";\n\n return;\n }\n\n get(this.urlValue, {\n query: {\n type: selectedType,\n target: element.id,\n name: element.name,\n selected_subtype_id: selectedSubtype,\n },\n responseKind: \"turbo-stream\",\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"sum-it-color-picker\"\nexport default class extends Controller {\n // Ensure the currently selected color is highlighted\n connect() {\n const label = this.#currentlyCheckedLabel();\n this.#highlightSelectedColor(label);\n }\n\n hoverOption(event) {\n this.#highlightSelectedColor(event.currentTarget);\n }\n\n leaveOption(event) {\n const inputRadioId = event.currentTarget.querySelectorAll(\"label\")[0].htmlFor;\n const inputRadio = document.getElementById(inputRadioId) as HTMLInputElement;\n\n if (!inputRadio.checked) {\n const labelBorder = event.currentTarget.querySelectorAll('.color-circle-option-border')[0];\n labelBorder.style.borderColor = 'transparent';\n }\n }\n\n selectOption(event) {\n const colorPickerPreview = document.getElementById('color_picker_preview');\n const colorPickerPreviewText = colorPickerPreview.querySelectorAll('.color-circle-option-text')[0] as HTMLElement;\n const labelColor = event.currentTarget.querySelectorAll('.color-circle-option')[0];\n const labelText = event.currentTarget.querySelectorAll('.color-circle-option-text')[0];\n\n colorPickerPreview.style.backgroundColor = labelColor.style.backgroundColor;\n labelColor.closest('.color-circle-option-border').style.borderColor = labelColor.style.backgroundColor;\n colorPickerPreviewText.style.color = labelText.style.color;\n\n const label = this.#currentlyCheckedLabel();\n const labelBorder = label.querySelectorAll('.color-circle-option-border')[0] as HTMLElement;\n labelBorder.style.borderColor = 'transparent';\n }\n\n #currentlyCheckedLabel() {\n const currentlyChecked = document.querySelector('input[name=\"tag_group[color]\"]:checked');\n const label = document.querySelector(\"label[for='\" + currentlyChecked.id + \"']\");\n return label;\n }\n\n #highlightSelectedColor(el) {\n const labelColor = el.querySelectorAll('.color-circle-option')[0];\n const labelBorder = el.querySelectorAll('.color-circle-option-border')[0];\n labelBorder.style.borderColor = labelColor.style.backgroundColor;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { delegate, Instance as TippyInstance } from \"tippy.js\";\n\n// Connects to data-controller=\"table\"\nexport default class extends Controller {\n declare tippy: TippyInstance;\n\n static targets = [\"cell\"];\n\n declare cellTargets: HTMLElement[];\n\n connect() {\n this.tippy = delegate(this.element, { target: \"span.cell\", onShow: this.onShow });\n }\n\n disconnect() {\n this.tippy.destroy();\n }\n\n onShow(instance: TippyInstance): void | false {\n const target = instance.reference as HTMLElement;\n const targetHasText = target?.title || target?.innerText?.trim();\n\n if (target?.title) {\n instance.setContent(target.title);\n } else {\n instance.setContent(target.innerText.trim());\n }\n\n if (target && targetHasText && target.offsetWidth < target.scrollWidth) {\n return;\n } else {\n // If the content is not truncated, don't show the tooltip\n return false;\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\nimport TomSelect from \"tom-select\";\nimport { TomOption, TomInput } from \"tom-select/dist/cjs/types\";\nimport { loadingIcon } from \"../helpers\";\n\ninterface Tag {\n id: string;\n name: string;\n colorBg: string;\n colorFg: string;\n tagGroupId: string;\n tagGroupName: string;\n tagGroupType: string;\n}\n\n// Connects to data-controller=\"tag-select\"\nexport default class extends Controller {\n static values = {\n classes: Array,\n itemClasses: Array,\n allowDuplicateTagGroup: Boolean,\n includeUntagged: {\n type: Boolean,\n default: false,\n },\n lock: Boolean,\n disabled: Boolean,\n tagUrl: String,\n id: String,\n };\n\n static targets = [\"selectElement\"];\n\n declare select: TomSelect;\n declare hasClassesValue: boolean;\n declare hasItemClassesValue: boolean;\n declare classesValue: string[];\n declare itemClassesValue: string[];\n declare allowDuplicateTagGroupValue: boolean;\n declare includeUntaggedValue: boolean;\n declare lockValue: boolean;\n declare disabledValue: boolean;\n declare tagUrlValue: string;\n declare hasTagUrlValue: boolean;\n declare idValue: string;\n declare hasIdValue: string;\n\n declare selectElementTarget: HTMLSelectElement;\n\n declare templateElements: Array;\n\n connect() {\n let plugins = [\"remove_button\"];\n\n if (this.lockValue) {\n plugins = [];\n }\n\n this.templateElements = Array.from(this.element.querySelectorAll(\"template\"));\n\n const options = {\n plugins: plugins,\n preload: \"focus\",\n load: this.loadOptions.bind(this),\n score: this.scoreSearchResults,\n maxOptions: 100,\n hidePlaceholder: true,\n valueField: \"id\",\n labelField: \"name\",\n searchField: [\"name\"],\n optgroupField: \"tagGroupId\",\n optgroupLabelField: \"tagGroupName\",\n optgroupValueField: \"tagGroupId\",\n onBlur: () => {\n // We want the options to reload when the user focuses on the select\n this.select.wrapper.classList.remove(\"preloaded\");\n this.select.clearOptions();\n this.select.settings.load = this.loadOptions.bind(this);\n },\n render: {\n option: (item: Tag, escape: (value: string) => string) => {\n if (item.id === \"untagged\") {\n return this.buildUntaggedOption(item, escape);\n } else if (item.id.startsWith(\"not_tagged_with_\")) {\n return ``; // Don't render, this is a ghost option\n } else {\n return this.buildTagOption(item, escape);\n }\n },\n item: (item: Tag, escape: (value: string) => string) => {\n if (item.id === \"untagged\" || item.id.startsWith(\"not_tagged_with_\")) {\n return this.buildUntaggedItem(item, escape);\n } else {\n return this.buildTagItem(item, escape);\n }\n },\n optgroup_header: (data: Tag, escape: (value: string) => string) => {\n if (data.tagGroupId === \"untagged\") {\n return \"\";\n }\n const optGroupHeader = this.tempEl(\"optgroupHeader\");\n optGroupHeader.firstElementChild.textContent = this.decodeHtmlEntities(escape(data.tagGroupName));\n optGroupHeader.append(this.buildNoGroupButton(data));\n optGroupHeader.append(this.buildNewButton(data));\n return optGroupHeader;\n },\n loading: (_data, _escape) => {\n return `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n },\n },\n onChange: (_values: string[]) => {\n this.updateDisabledStates();\n },\n onItemAdd: (values: string[]) => {\n this.select.setTextboxValue(\"\");\n this.select.refreshOptions();\n this.toggleUntaggedSelection(values);\n },\n onInitialize: () => {\n if (this.allowAddNewButton()) {\n const dropdown = this.selectElementTarget.nextElementSibling.querySelector(\".ts-dropdown\");\n\n dropdown.appendChild(this.tempEl(\"fullNewButton\"));\n }\n },\n };\n\n if (this.allowMultipleTagsPerGroup) {\n options[\"onChange\"] = null;\n }\n\n this.select = new TomSelect(this.selectElementTarget as TomInput, options);\n\n if (!this.allowMultipleTagsPerGroup) {\n this.updateDisabledStates();\n }\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n this.select.control.classList.add(className);\n });\n }\n\n if (this.lockValue) {\n this.select.lock();\n }\n\n if (this.disabledValue) {\n this.disableSelect();\n }\n }\n\n selectOption(optionId: string) {\n this.select.addItem(optionId);\n }\n\n tempEl(templateName) {\n const template = this.templateElements.find((element) => {\n if (element.dataset.templateName === templateName) {\n return element;\n }\n });\n\n return template.content.firstElementChild.cloneNode(true) as HTMLElement;\n }\n\n allowAddNewButton() {\n const whitelist = [\n new RegExp(\"/ledger_management/journal_entries/new\"),\n new RegExp(\"/ledger_management/ledger_transactions/lt_(.*)/edit$\"),\n new RegExp(\"/ledger_management/ledger_transactions/lt_(.*)/duplicate$\"),\n new RegExp(\"/ledger_management/ledger_transactions/lt_(.*)/reverse$\"),\n new RegExp(\"/ledger_management/multi_ledger_transactions/mlt_(.*)/edit$\"),\n new RegExp(\"/account_reconciliation/connected_transactions\"),\n new RegExp(\"/payables_management(.*)\"),\n ];\n\n for (const regex of whitelist) {\n if (regex.test(window.location.href)) {\n return true;\n }\n }\n\n return false;\n }\n\n buildNoGroupButton(data) {\n if (!this.includeUntaggedValue) {\n return \"\";\n }\n\n const iconNoTagGroupButton = this.tempEl(\"iconNoTagGroupButton\");\n const innerButton = iconNoTagGroupButton.firstElementChild as HTMLElement;\n\n innerButton.setAttribute(\"data-action\", \"click->tag-select#addNoGroupTag\");\n innerButton.setAttribute(\"data-tag-group-id\", data.tagGroupId);\n\n return iconNoTagGroupButton;\n }\n\n addNoGroupTag(event) {\n const tagGroupId = event.currentTarget.dataset.tagGroupId;\n this.select.addItem(`not_tagged_with_${tagGroupId}`);\n\n // remove any other tags from the tag group\n for (const value in this.select.options) {\n const tag = this.select.options[value];\n const tagInTagGroup = tag.tagGroupId === tagGroupId && tag.id !== `not_tagged_with_${tagGroupId}`;\n if (tagInTagGroup || tag.id === \"untagged\") {\n this.select.removeItem(tag.id);\n }\n }\n }\n\n buildNewButton(data) {\n if (!this.allowAddNewButton() || data.tagGroupType !== \"user\") {\n return \"\";\n }\n\n const iconNewButton = this.tempEl(\"iconNewButton\");\n const innerButton = iconNewButton.firstElementChild as HTMLElement;\n const card = JSON.parse(innerButton.dataset.card);\n const cardTurboSrcUrl = new URL(card.turboSrc, window.location.origin);\n cardTurboSrcUrl.searchParams.append(\"tag_group_id\", data.tagGroupId);\n\n card.turboSrc = cardTurboSrcUrl.pathname + cardTurboSrcUrl.search;\n card.turboId = `tag_form_with_group_tag_${data.tagGroupId}_tag`;\n\n innerButton.dataset.card = JSON.stringify(card);\n\n return iconNewButton;\n }\n\n handleIdEnabledEvent(event) {\n const isEnabled = event.detail.enabled;\n const id = event.detail.id;\n\n if (this.hasIdValue && this.idValue === id) {\n if (isEnabled) {\n this.enableSelect();\n } else {\n this.disableSelect();\n }\n }\n }\n\n handleToggleEvent(event) {\n const isChecked = event.detail.checked;\n\n if (isChecked) {\n this.disableSelect();\n } else {\n this.enableSelect();\n }\n }\n\n enableSelect() {\n this.select.enable();\n }\n\n disableSelect() {\n this.select.disable();\n this.select.clear();\n }\n\n updateDisabledStates() {\n if (this.allowMultipleTagsPerGroup) {\n return;\n }\n const selectedTagIds = this.select.items;\n const selectedTagGroupIds = selectedTagIds.map((id) => this.select.options[id].tagGroupId);\n\n this.disableOptionsForGroupIds(selectedTagGroupIds);\n }\n\n toggleUntaggedSelection(values: string[]) {\n const isUntaggedSelected = values.includes(\"untagged\");\n\n if (isUntaggedSelected) {\n for (const value in this.select.options) {\n const tag = this.select.options[value];\n if (tag.id !== \"untagged\") {\n this.select.removeItem(tag.id);\n }\n }\n } else {\n this.select.removeOption(\"untagged\");\n }\n\n // get all tag group ids from the selected tags\n let notTaggedWithTagGroupIds: string[] = [];\n if (Array.isArray(values)) {\n const notTaggedWithTagGroupIds = [];\n values.map((id) => {\n if (!id.startsWith(\"not_tagged_with_\")) {\n notTaggedWithTagGroupIds.push(`not_tagged_with_${this.select.options[id].tagGroupId}`);\n }\n });\n } else {\n if (!(values as string).startsWith(\"not_tagged_with_\")) {\n notTaggedWithTagGroupIds = [`not_tagged_with_${this.select.options[values].tagGroupId}`];\n }\n }\n\n // we want to remove any pre-existing not_tagged_with options if we select a tag\n // with a tag group id that matches the not_tagged_with option\n for (const value in this.select.options) {\n const tag = this.select.options[value];\n if (notTaggedWithTagGroupIds.includes(tag.id)) {\n this.select.removeItem(tag.id);\n }\n }\n }\n\n disableOptionsForGroupIds(groupIds: string[]) {\n for (const value in this.select.options) {\n const data = this.select.options[value];\n const wasDisabled = data.disabled;\n data.disabled = groupIds.includes(data.tagGroupId);\n\n if (wasDisabled != data.disabled) {\n this.select.updateOption(value, data);\n }\n }\n }\n\n disconnect() {\n this.select.destroy();\n }\n\n // Build out the optgroup data structure for TomSelect\n buildOptGroups(tags: Tag[]): TomOption[] {\n const tagGroups = tags.reduce((groups, tag) => {\n if (!groups[tag.tagGroupId]) {\n groups[tag.tagGroupId] = {\n tagGroupName: tag.tagGroupName,\n tagGroupId: tag.tagGroupId,\n tagGroupType: tag.tagGroupType,\n };\n }\n return groups;\n }, {});\n\n if (this.includeUntaggedValue) {\n tagGroups[0] = this.untaggedTagGroupDefinition();\n }\n\n return Object.values(tagGroups);\n }\n\n loadOptions(_query: string, callback: (tags: Tag[] | void, optionGroups: TomOption[] | void) => void) {\n if (this.select.loading > 1) {\n callback();\n return;\n }\n\n get(this.tagUrlValue, { responseKind: \"json\" })\n .then((response: Response) => response.json)\n .then((payload: Tag[]) => {\n const optionGroups = this.buildOptGroups(payload);\n\n if (this.includeUntaggedValue) {\n // Add \"Untagged\" to the beginning of the list\n payload.unshift(this.untaggedTagDefinition());\n\n // for each optionGroup, build an option for not having that tag group\n for (const optionGroup of optionGroups) {\n payload.push(this.notTaggedWithTagGroupDefinition(optionGroup));\n }\n }\n\n callback(payload, optionGroups);\n\n if (!this.allowMultipleTagsPerGroup) {\n this.updateDisabledStates();\n }\n\n // We only want to load the data once, so we set the load function to null\n this.select.settings.load = null;\n })\n .catch((error) => {\n console.error(error);\n\n callback();\n });\n }\n\n scoreSearchResults(search) {\n return (item) => {\n let score = 0;\n const lowerCaseName = item.name.toLowerCase();\n const lowerCaseTagGroupName = item.tagGroupName.toLowerCase();\n const lowerCaseSearch = search.toLowerCase();\n\n if (lowerCaseName === lowerCaseSearch) {\n score = 1;\n } else if (lowerCaseName.includes(lowerCaseSearch)) {\n score = 0.75;\n } else if (lowerCaseTagGroupName === lowerCaseSearch) {\n score = 0.5;\n } else if (lowerCaseTagGroupName.includes(lowerCaseSearch)) {\n score = 0.25;\n }\n\n return score;\n };\n }\n\n get allowMultipleTagsPerGroup() {\n return this.allowDuplicateTagGroupValue;\n }\n\n buildUntaggedOption(item, escape: (value: string) => string) {\n const style = `style=\"background-color: ${item.colorBg}; color: ${item.colorFg};\"`;\n return `\n
\n \n ${escape(item.name)}\n \n
\n `;\n }\n\n buildTagOption(item, escape: (value: string) => string) {\n const style = `style=\"background-color: ${item.colorBg}; color: ${item.colorFg};\"`;\n return `\n
\n \n ${escape(item.name)}\n \n
\n `;\n }\n\n buildUntaggedItem(item, escape: (value: string) => string) {\n const style = `style=\"background-color: ${item.colorBg}; color: ${item.colorFg};\"`;\n\n return `\n
\n ${escape(item.name)}\n
\n `;\n }\n\n buildTagItem(item, escape: (value: string) => string) {\n const style = `style=\"background-color: ${item.colorBg}; color: ${item.colorFg};\"`;\n let itemClasses = \"\";\n if (this.hasItemClassesValue) {\n itemClasses = this.itemClassesValue.join(\" \");\n }\n\n return `\n
\n ${escape(item.tagGroupName + \": \" + item.name)}\n
\n `;\n }\n\n untaggedTagGroupDefinition() {\n return {\n tagGroupName: \"Untagged\",\n tagGroupId: \"untagged\",\n tagGroupType: \"system\",\n };\n }\n\n untaggedTagDefinition() {\n return {\n id: \"untagged\",\n name: \"Untagged\",\n colorBg: \"#ffffff\",\n colorFg: \"#000000\",\n tagGroupId: \"untagged\",\n tagGroupName: \"Untagged\",\n tagGroupType: \"system\",\n };\n }\n\n notTaggedWithTagGroupDefinition(optionGroup) {\n return {\n id: `not_tagged_with_${optionGroup.tagGroupId}`,\n name: `Not Tagged w/ ${optionGroup.tagGroupName}`,\n colorBg: \"#ffffff\",\n colorFg: \"#000000\",\n tagGroupId: optionGroup.tagGroupId,\n tagGroupName: optionGroup.tagGroupName,\n tagGroupType: optionGroup.tagGroupType,\n };\n }\n\n // creates a temporary
, assigns the encoded string to its innerHTML, and retrieves\n // the decoded string from textContent to display special characters properly\n decodeHtmlEntities(encodedString) {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = encodedString;\n return tempDiv.textContent || tempDiv.innerText || \"\";\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { get } from \"@rails/request.js\";\n\n// Connects to data-controller=\"tax-classification-select\"\nexport default class extends Controller {\n static targets = [\"section\", \"source\", \"taxClassificationSelect\"];\n\n static values = {\n taxClassificationSelectUrl: String\n };\n\n declare sourceTarget: HTMLInputElement;\n declare sectionTargets: HTMLDivElement[];\n declare taxClassificationSelectTarget: HTMLSelectElement;\n declare hasTaxClassificationSelectTarget: boolean;\n declare taxClassificationSelectUrlValue: string;\n\n connect() {\n const startingValue = this.handleInputAmbiguity(this.sourceTarget);\n\n this.toggleVisibility(startingValue);\n }\n\n handleChange(event) {\n const selectedValue = this.handleInputAmbiguity(event.target);\n\n this.toggleVisibility(selectedValue);\n\n if (this.hasTaxClassificationSelectTarget) {\n this.taxClassificationSelectTarget.innerHTML = \"\";\n }\n }\n\n toggleVisibility(value) {\n this.sectionTargets.forEach((section) => {\n const showWhens = section.dataset.showWhen.split(\",\").map((showWhen) => showWhen.trim());\n\n if (this.willDisplaySection(value, showWhens) && this.shouldMakeRequest(section)) {\n this.getTaxClassificationSelectOptions(value);\n }\n\n showWhens.forEach(() => {\n if (this.willDisplaySection(value, showWhens)) {\n section.classList.remove(\"hidden\");\n } else {\n section.classList.add(\"hidden\");\n }\n });\n });\n }\n\n shouldMakeRequest(section) {\n return section.dataset.requestSelect === \"true\";\n }\n\n willDisplaySection(value, showWhens) {\n return value === true || (showWhens.includes(value) && value !== \"\");\n }\n\n getTaxClassificationSelectOptions(value) {\n const url = new URL(this.taxClassificationSelectUrlValue);\n const params = new URLSearchParams(url.search);\n params.append(\"entity_type\", value);\n url.search = params.toString();\n get(url.toString(), {\n responseKind: \"turbo-stream\",\n });\n }\n\n handleInputAmbiguity(target) {\n // If target is a checkbox, use that\n if (target.getAttribute(\"type\") === \"checkbox\") {\n return target.checked;\n } else {\n return target.value;\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"template\"\nexport default class extends Controller {\n static targets = [\"template\", \"target\"];\n\n declare templateTarget: HTMLTemplateElement;\n declare targetTarget: HTMLElement;\n\n render() {\n this.targetTarget.insertAdjacentHTML(\"beforebegin\", this.templateTarget.innerHTML)\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"toggle-all\"\nexport default class extends Controller {\n static targets = [\"toggleable\", \"toggleButton\", \"actionIcon\"];\n static values = {\n open: { type: Boolean, default: false },\n };\n\n declare toggleableTargets: HTMLElement[];\n\n declare actionIconTarget: HTMLElement;\n declare hasActionIconTarget: boolean;\n\n declare openValue: boolean;\n\n connect() {\n if (this.hasActionIconTarget) {\n this.actionIconTarget.classList.add(\"transition-transform\", \"duration-200\", \"ease-in-out\");\n\n if (this.openValue) {\n this.actionIconTarget.classList.add(\"rotate-0\");\n } else {\n this.actionIconTarget.classList.add(\"-rotate-90\");\n }\n }\n }\n\n toggleAll(_e: Event): void {\n this.openValue = !this.openValue;\n this.animate();\n }\n\n collapseAll(_e: Event): void {\n this.openValue = false;\n this.animate();\n }\n\n expandAll(_e: Event): void {\n this.openValue = true;\n this.animate()\n }\n\n animate() {\n if (this.hasActionIconTarget) {\n if (this.openValue) {\n this.actionIconTarget.classList.add(\"rotate-0\");\n this.actionIconTarget.classList.remove(\"-rotate-90\");\n } else {\n this.actionIconTarget.classList.add(\"-rotate-90\");\n this.actionIconTarget.classList.remove(\"rotate-0\");\n }\n }\n\n this.toggleableTargets.forEach((toggleable: HTMLElement) => {\n if (this.openValue) {\n this.dispatch(\"expand\", { target: toggleable });\n } else {\n this.dispatch(\"collapse\", { target: toggleable });\n }\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n/**\n * Handles toggling classes on elements based on their default active state.\n *\n * Targets:\n * - toggleable: Elements that will have classes toggled\n *\n * Classes:\n * - toggle: Classes to toggle on the toggleable targets\n *\n * Data Attributes:\n * - data-default-active: \"true\" | \"false\" - Determines the default state of a toggleable target\n *\n * Example:\n * ```html\n *
\n *
Show by default
\n *
Hide by default
\n *
\n * ```\n */\n\n// Connects to data-controller=\"toggle-class\"\nexport default class extends Controller {\n static classes = [\"toggle\"];\n static targets = [\"toggleable\"];\n\n declare toggleableTargets: HTMLElement[];\n declare toggleClasses: string[];\n\n toggle(): void {\n this.toggleableTargets.forEach(this.toggleClassesOnTarget);\n }\n\n addClass(): void {\n this.toggleableTargets.forEach((target) => {\n this.setClassesOnTarget(target, true);\n });\n }\n\n removeClass(): void {\n this.toggleableTargets.forEach((target) => {\n this.setClassesOnTarget(target, false);\n });\n }\n\n private toggleClassesOnTarget = (target: HTMLElement): void => {\n this.toggleClasses.forEach((toggleClass) => {\n target.classList.toggle(toggleClass);\n });\n };\n\n private setClassesOnTarget(target: HTMLElement, isAddingClass: boolean): void {\n const isDefaultActive = target.dataset.defaultActive === \"true\";\n const shouldAddClass = isDefaultActive ? !isAddingClass : isAddingClass;\n\n this.toggleClasses.forEach((toggleClass) => {\n if (shouldAddClass) {\n target.classList.add(toggleClass);\n } else {\n target.classList.remove(toggleClass);\n }\n });\n }\n}\n","import { Toggle } from \"tailwindcss-stimulus-components\";\n\n// Connects to data-controller=\"toggle\"\nexport default class extends Toggle {\n static targets = [\"toggleable\", \"actionIcon\"];\n static values = {\n open: { type: Boolean, default: false },\n };\n\n declare toggleableTargets: HTMLElement[];\n\n declare actionIconTarget: HTMLElement;\n declare hasActionIconTarget: boolean;\n\n declare openValue: boolean;\n\n connect() {\n super.connect();\n\n if (this.hasActionIconTarget) {\n this.actionIconTarget.classList.add(\"transition-transform\", \"duration-200\", \"ease-in-out\");\n\n if (this.openValue) {\n this.actionIconTarget.classList.add(\"rotate-0\");\n } else {\n this.actionIconTarget.classList.add(\"-rotate-90\");\n }\n }\n }\n\n animate() {\n if (this.hasActionIconTarget) {\n if (this.openValue) {\n this.actionIconTarget.classList.add(\"rotate-0\");\n this.actionIconTarget.classList.remove(\"-rotate-90\");\n } else {\n this.actionIconTarget.classList.add(\"-rotate-90\");\n this.actionIconTarget.classList.remove(\"rotate-0\");\n }\n }\n\n super.animate();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"toggle-disable\"\nexport default class extends Controller {\n static targets = [\"primaryCheckbox\", \"dependentInput\"];\n declare primaryCheckboxTarget: HTMLInputElement;\n declare dependentInputTargets: HTMLInputElement[];\n\n static values = {\n dependent: String,\n };\n\n declare dependentValue: string;\n\n connect() {\n this.toggleDependentInputs();\n }\n\n disableDependentIfCheckboxIsChecked() {\n const checkboxToDisable: HTMLInputElement = document.querySelector(this.dependentValue);\n\n if (this.primaryCheckboxTarget.checked) {\n checkboxToDisable.disabled = false;\n } else {\n checkboxToDisable.checked = false;\n checkboxToDisable.disabled = true;\n }\n }\n\n toggleDependentInputs() {\n this.dependentInputTargets.forEach((dependentInput) => {\n if (this.primaryCheckboxTarget.checked) {\n dependentInput.disabled = false;\n } else {\n dependentInput.checked = false;\n dependentInput.value = \"\";\n dependentInput.disabled = true;\n }\n });\n }\n}\n","import { Toggle } from \"tailwindcss-stimulus-components\";\n\n// Connects to data-controller=\"toggle-permissions\"\nexport default class extends Toggle {\n declare openValue: boolean;\n\n toggle(event) {\n const input = event.target as HTMLInputElement;\n\n if (input.dataset.open === \"true\") {\n super.show();\n } else if (this.openValue) {\n super.hide();\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\n\n// Connects to data-controller=\"toggle-readonly\"\nexport default class extends Controller {\n connect() {}\n\n static targets = [\"numberInput\"];\n\n declare numberInputTarget: HTMLInputElement;\n\n toggleReadOnly(event: Event): void {\n event.preventDefault();\n this.numberInputTarget.readOnly = !this.numberInputTarget.readOnly;\n\n this.updateButtonText(event.target as HTMLElement);\n }\n\n updateButtonText(button: HTMLElement): void {\n if (button) {\n button.textContent = this.numberInputTarget.readOnly\n ? \"Edit\"\n : \"Lock\";\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"transaction-payables-match\"\nexport default class extends Controller {\n static targets = [\n \"payableIdInput\",\n \"payableIdInputTemplate\",\n \"payableIdInputContainer\",\n \"checkbox\",\n \"checkboxAll\"\n ];\n\n declare payableIdInputTemplateTarget: HTMLTemplateElement;\n declare payableIdInputTargets: HTMLInputElement[];\n declare payableIdInputContainerTarget: HTMLDivElement;\n\n declare checkboxTargets: HTMLInputElement[];\n declare checkboxAllTarget: HTMLInputElement;\n\n updateMatches() {\n this.setHiddenTransactionInputs();\n }\n\n setHiddenTransactionInputs() {\n const selectedCheckboxes = this.getSelectedCheckboxes();\n\n this.payableIdInputContainerTarget.innerHTML = \"\";\n\n selectedCheckboxes.forEach((checkbox) => {\n const payableIdInput = document.importNode(this.payableIdInputTemplateTarget.content, true);\n const payableIdInputEl = payableIdInput.querySelector(\"input\");\n payableIdInputEl.value = checkbox.value;\n\n this.payableIdInputContainerTarget.appendChild(payableIdInput);\n });\n }\n\n getSelectedCheckboxes() {\n return this.checkboxTargets.filter((checkbox) => {\n return checkbox.checked;\n });\n }\n\n selectAll() {\n this.checkboxTargets.forEach((checkbox) => {\n checkbox.checked = true;\n });\n }\n\n deselect(checkboxes: HTMLInputElement[]) {\n checkboxes.forEach((checkbox) => {\n checkbox.checked = false;\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { TomInput } from \"tom-select/dist/cjs/types\";\n\n// Connects to data-controller=\"transaction-transfer\"\nexport default class extends Controller {\n declare submitButtonTarget: HTMLButtonElement;\n declare rowTargets: HTMLElement[];\n declare destinationDescriptionTargets: HTMLElement[];\n declare accountCodeSelectTargets: HTMLInputElement[];\n declare tagSelectTargets: HTMLInputElement[];\n declare intercompanyAccountSelectTargets: HTMLInputElement[];\n\n static targets = [\n \"submitButton\",\n \"row\",\n \"destinationDescription\",\n \"accountCodeSelect\",\n \"tagSelect\",\n \"intercompanyAccountSelect\",\n ];\n\n static values = {\n originalLedgerId: String,\n };\n declare originalLedgerIdValue: string;\n\n clearNonSelectedRows(event: Event) {\n const target = event.target as HTMLInputElement;\n\n this.destinationDescriptionTargets.forEach((destinationDescription: HTMLElement) => {\n const destinationDescriptionTransactionId = destinationDescription.getAttribute(\n \"data-destination-description-id-value\",\n );\n const destinationDescriptionValue = destinationDescription.getAttribute(\"data-destination-description-value\");\n\n if (destinationDescriptionTransactionId !== target.value) {\n const divElement = document.createElement(\"div\");\n divElement.textContent = destinationDescriptionValue;\n divElement.classList.add(\"p-2\");\n destinationDescription.textContent = \"\";\n destinationDescription.appendChild(divElement);\n } else {\n const textareaElement = document.createElement(\"textarea\");\n textareaElement.setAttribute(\"name\", \"destination_transaction_description\");\n textareaElement.textContent = destinationDescriptionValue;\n textareaElement.classList.add(\n \"flex\",\n \"px-2\",\n \"border-none\",\n \"shadow-none\",\n \"rounded-none\",\n \"focus:ring-inset\",\n \"h-full\",\n \"w-full\",\n \"text-sm\",\n \"font-medium\",\n \"text-sumit-primary-gray-dark\",\n \"min-h-8\",\n );\n\n destinationDescription.textContent = \"\";\n destinationDescription.appendChild(textareaElement);\n }\n });\n\n this.accountCodeSelectTargets.forEach((accountCodeSelect: HTMLElement) => {\n const accountCodeSelectTransactionId = accountCodeSelect.getAttribute(\"data-account-code-select-id-value\");\n\n const accountCodeSelectElement = accountCodeSelect as TomInput;\n const accountCodeTomSelect = accountCodeSelectElement.tomselect;\n if (accountCodeSelectTransactionId === target.value) {\n accountCodeTomSelect.enable();\n this.toggleAccountCodeSelect(accountCodeSelectTransactionId, true);\n } else {\n accountCodeTomSelect.disable();\n accountCodeTomSelect.clear();\n this.toggleAccountCodeSelect(accountCodeSelectTransactionId, false);\n }\n });\n\n this.tagSelectTargets.forEach((tagSelect: HTMLElement) => {\n const tagSelectTransactionId = tagSelect.getAttribute(\"data-tag-select-id-value\");\n\n const tagSelectElement = tagSelect as TomInput;\n const tagTomSelect = tagSelectElement.tomselect;\n if (tagSelectTransactionId === target.value) {\n tagTomSelect.enable();\n this.toggleTagSelect(tagSelectTransactionId, true);\n } else {\n tagTomSelect.disable();\n tagTomSelect.clear();\n this.toggleTagSelect(tagSelectTransactionId, false);\n }\n });\n\n this.intercompanyAccountSelectTargets.forEach((intercompanyAccountSelect: HTMLInputElement) => {\n const intercompanyAccountSelectTransactionId = intercompanyAccountSelect.getAttribute(\n \"data-intercompany-account-select-transaction-id-value\",\n );\n const intercompanyAccountSelectLedgerId = intercompanyAccountSelect.getAttribute(\n \"data-intercompany-account-select-ledger-id-value\",\n );\n\n if (\n intercompanyAccountSelectTransactionId === target.value &&\n intercompanyAccountSelectLedgerId !== this.originalLedgerIdValue\n ) {\n intercompanyAccountSelect.disabled = false;\n } else {\n intercompanyAccountSelect.disabled = true;\n intercompanyAccountSelect.value = \"\";\n intercompanyAccountSelect.dispatchEvent(new Event(\"change\"));\n }\n });\n\n const targetLedgerId = target.getAttribute(\"data-transaction-transfer-ledger-id-value\");\n\n if (targetLedgerId !== this.originalLedgerIdValue) {\n this.disableSubmit();\n } else {\n this.enableSubmit();\n }\n }\n\n toggleAccountCodeSelect(id: string, enabled: boolean) {\n this.dispatch(\"toggleAccountCodeSelect\", { detail: { enabled: enabled, id: id } });\n }\n\n toggleTagSelect(id: string, enabled: boolean) {\n this.dispatch(\"toggleTagSelect\", { detail: { enabled: enabled, id: id } });\n }\n\n handleToggleSubmitEvent(event) {\n const isEnabled = event.detail.enabled;\n const submitId = event.detail.id;\n\n if (this.submitButtonTarget.id === submitId) {\n if (isEnabled) {\n this.enableSubmit();\n } else {\n this.disableSubmit();\n }\n }\n }\n\n enableSubmit() {\n this.submitButtonTarget.disabled = false;\n }\n\n disableSubmit() {\n this.submitButtonTarget.disabled = true;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"unsaved-changes\"\nexport default class extends Controller {\n declare observer: MutationObserver;\n declare noticeActivated: boolean;\n declare boundInputChangedFn: () => void;\n declare boundTurboBeforeVisitFn: (e) => void;\n declare boundBeforeUnloadFn: (e) => void;\n declare boundSubmitHandlerFn: () => void;\n declare turboBeforeVisitTriggered: boolean;\n declare formSubmitted: boolean;\n\n connect() {\n this.noticeActivated = false;\n this.formSubmitted = false;\n // this flag is here in order to prevent the beforeunload event from firing\n // if turbo event has fired. For some reason the \"Register\" link in the navbar triggers both events.\n this.turboBeforeVisitTriggered = false;\n\n this.boundInputChangedFn = this.inputChanged.bind(this);\n this.boundTurboBeforeVisitFn = this.turboBeforeVisit.bind(this);\n this.boundBeforeUnloadFn = this.beforeUnload.bind(this);\n this.boundSubmitHandlerFn = this.formSubmittedHandler.bind(this);\n\n this.observer = new MutationObserver(() => {\n const inputs = this.getInputs();\n inputs.forEach(input => {\n this.addInputChangedListeners(input);\n });\n\n const submits = this.getSubmitButtons();\n submits.forEach(input => {\n input.removeEventListener('click', this.boundSubmitHandlerFn);\n input.addEventListener('click', this.boundSubmitHandlerFn);\n });\n\n });\n\n const config = {\n childList: true,\n attributes: false,\n subtree: true,\n };\n\n this.observer.observe(document, config);\n }\n\n getInputs() {\n return this.element.querySelectorAll('input, select, textarea')\n }\n\n getSubmitButtons() {\n return this.element.querySelectorAll('button[type=\"submit\"]');\n }\n\n formSubmittedHandler() {\n this.formSubmitted = true;\n }\n\n addInputChangedListeners(input) {\n input.addEventListener('input', this.boundInputChangedFn);\n }\n\n inputChanged() {\n this.turboBeforeVisitTriggered = false;\n this.activateNotice();\n }\n\n activateNotice() {\n if (this.noticeActivated) return;\n\n window.addEventListener('turbo:before-visit', this.boundTurboBeforeVisitFn)\n window.addEventListener('beforeunload', this.boundBeforeUnloadFn)\n this.noticeActivated = true;\n this.removeAllInputChangedListeners();\n }\n\n turboBeforeVisit(e) {\n if (this.formSubmitted) return;\n\n if (confirm(\"Are you sure you want to navigate away from this page? You will lose any unsaved changes.\")) {\n this.turboBeforeVisitTriggered = true;\n } else {\n e.preventDefault();\n this.turboBeforeVisitTriggered = false;\n }\n }\n\n beforeUnload(e) {\n if (this.formSubmitted) return;\n\n if (this.turboBeforeVisitTriggered) {\n e.preventDefault();\n this.turboBeforeVisitTriggered = false;\n return;\n }\n e.preventDefault();\n e.returnValue = '';\n }\n\n removeAllSubmitButtonsListeners() {\n const submits = this.getSubmitButtons();\n submits.forEach(input => {\n input.removeEventListener('click', this.boundSubmitHandlerFn);\n });\n }\n\n removeAllInputChangedListeners() {\n const inputs = this.getInputs();\n inputs.forEach(input => {\n input.removeEventListener('input', this.boundInputChangedFn);\n });\n }\n\n disconnect() {\n this.observer.disconnect();\n window.removeEventListener('turbo:before-visit', this.boundTurboBeforeVisitFn)\n window.removeEventListener('beforeunload', this.boundBeforeUnloadFn)\n this.removeAllSubmitButtonsListeners();\n this.removeAllInputChangedListeners();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { GridOptions, createGrid, GetRowIdParams, RowSelectedEvent, ToolPanelDef, GridApi } from \"ag-grid-enterprise\";\nimport { dataTypeDefinitions } from \"../helpers/reports/formatters\";\n\n// Connects to data-controller=\"uploaded-transactions\"\nexport default class extends Controller {\n declare transactionDataValue: Array;\n declare hasTransactionDataValue: boolean;\n\n declare gridTarget: HTMLDivElement;\n\n declare gridOptions: GridOptions;\n declare gridApi: GridApi;\n declare pageSize: number;\n\n static targets = [\"grid\"];\n\n static values = {\n transactionData: Array,\n };\n\n connect() {\n this.pageSize = 50;\n\n const defaultNumberColDef = {\n width: 180,\n cellDataType: \"number\",\n filter: \"agNumberColumnFilter\",\n filterParams: {\n maxNumConditions: 1,\n filterOptions: [\n \"equals\",\n \"notEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"inRange\",\n ],\n },\n cellClass: [\"ag-right-aligned-cell\", \"font-mono\"],\n sortable: true,\n };\n\n this.gridOptions = {\n columnDefs: [\n {\n field: \"date\",\n width: 140,\n sortable: true,\n cellClass: \"font-mono\",\n filter: \"agDateColumnFilter\",\n filterParams: {\n maxNumConditions: 1,\n },\n },\n { field: \"entity\", width: 200 },\n { field: \"account\", width: 240 },\n { field: \"description\", sortable: true, minWidth: 120, flex: 1, filter: \"agTextColumnFilter\" },\n { field: \"amount\", headerName: \"Amount\", ...defaultNumberColDef },\n {\n field: \"debits\",\n headerTooltip: \"This is the amount that will be shown as a debit when creating journal entries.\",\n ...defaultNumberColDef,\n },\n {\n field: \"credits\",\n headerTooltip: \"This is the amount that will be shown as a credit when creating journal entries.\",\n ...defaultNumberColDef,\n },\n ],\n defaultColDef: {\n sortable: false,\n },\n getRowId: (params: GetRowIdParams) => params.data.id.toString(),\n statusBar: {\n statusPanels: [{ statusPanel: \"agSelectedRowCountComponent\" }, { statusPanel: \"agAggregationComponent\" }],\n },\n sideBar: {\n toolPanels: [\n {\n id: \"columns\",\n labelDefault: \"Columns\",\n labelKey: \"columns\",\n iconKey: \"columns\",\n toolPanel: \"agColumnsToolPanel\",\n toolPanelParams: {\n suppressPivots: true,\n suppressPivotMode: true,\n },\n } as ToolPanelDef,\n \"filters\",\n ],\n },\n dataTypeDefinitions: {\n ...dataTypeDefinitions,\n },\n allowContextMenuWithControlKey: true,\n tooltipShowDelay: 100,\n onRowSelected: (_event: RowSelectedEvent) => {\n // TODO: Implement\n },\n };\n\n this.gridOptions.rowData = this.getTransactionData();\n\n this.gridApi = createGrid(this.gridTarget, this.gridOptions);\n }\n\n getTransactionData() {\n return this.transactionDataValue;\n }\n\n disconnect() {\n this.gridApi.destroy();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// Connects to data-controller=\"url-history-handler\"\nexport default class extends Controller {\n pushState(e: CustomEvent) {\n history.pushState(history.state, \"\", e.detail.url.href);\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport TomSelect from \"tom-select\";\nimport { post, get } from \"@rails/request.js\";\nimport { loadingIcon } from \"../helpers\";\n\ninterface IVendor {\n id: string;\n name: string;\n}\n\n// Connects to data-controller=\"vendor-select\"\nexport default class extends Controller {\n declare select: TomSelect;\n\n static values = {\n vendorsUrl: String,\n classes: Array,\n multi: Boolean,\n closeAfterSelect: { type: Boolean, default: true },\n allowCreate: { type: Boolean, default: false },\n };\n\n declare vendorsUrlValue: string;\n declare hasVendorsUrlValue: boolean;\n declare allowCreateValue: boolean;\n declare multiValue: boolean;\n declare hasClassesValue: boolean;\n declare classesValue: string[];\n declare hasCloseAfterSelectValue: boolean;\n declare closeAfterSelectValue: boolean;\n\n connect() {\n let plugins = [\"remove_button\"];\n if (!this.multiValue) {\n plugins = [];\n }\n\n this.select = new TomSelect(this.element, {\n plugins: plugins,\n hidePlaceholder: true,\n valueField: \"id\",\n labelField: \"name\",\n searchField: [\"name\"],\n closeAfterSelect: this.closeAfterSelectValue,\n create: this.hasVendorsUrlValue && this.allowCreateValue ? this.createVendor.bind(this) : false,\n load: this.hasVendorsUrlValue ? this.searchVendor.bind(this) : false,\n render: {\n loading: (_data, _escape) => {\n return `\n
\n ${loadingIcon()}\n Loading...\n
\n `;\n },\n option: (data, escape) => {\n if (data.disabled || String(data.disabledLabel).toLowerCase() === \"true\") {\n return `\n
\n ${escape(data.name)}\n Deactivated\n
\n `;\n } else {\n return `\n
\n ${escape(data.name)}\n
\n `;\n }\n },\n },\n });\n\n if (this.hasClassesValue) {\n this.classesValue.forEach((className) => {\n this.select.control.classList.add(className);\n });\n }\n }\n\n async createVendor(input: string, callback: (vendor: IVendor) => void) {\n const response = await post(this.vendorsUrlValue, {\n body: JSON.stringify({ vendor: { name: input } }),\n responseKind: \"json\",\n });\n\n if (response.ok) {\n const vendor = await response.json;\n callback(vendor);\n }\n }\n\n async searchVendor(input: string, callback: (vendors: { id: string; name: string }[]) => void) {\n const url = new URL(this.vendorsUrlValue, window.location.href);\n url.searchParams.append(\"q\", input);\n\n const response = await get(url.toString(), {\n responseKind: \"json\",\n });\n\n if (response.ok) {\n const vendors = (await response.json) as IVendor[];\n callback(vendors);\n }\n }\n\n disconnect() {\n this.select.destroy();\n }\n\n unfocusSelect() {\n this.select.blur();\n }\n}\n","// Load all the controllers within this directory and all subdirectories.\n// Controller files must be named *_controller.js.\n\nimport { application } from \"./application\";\nimport { registerControllers } from \"stimulus-vite-helpers\";\n\nconst controllers = import.meta.glob(\"./**/*_controller.*\", { eager: true });\nregisterControllers(application, controllers);\n\nimport { Dropdown, Tabs, Slideover } from \"tailwindcss-stimulus-components\";\napplication.register(\"dropdown\", Dropdown);\napplication.register(\"tabs\", Tabs);\napplication.register(\"slideover\", Slideover);\n\nimport * as Flowbite from \"flowbite/dist/flowbite.turbo.js\";\n\napplication.register(\"flowbite\", Flowbite);\n","// Vite adds some functionality for import.meta - so we reference the types here:\n/// \n\nimport \"@hotwired/turbo-rails\";\nimport \"flowbite\";\nimport * as ActiveStorage from \"@rails/activestorage\";\nimport LocalTime from \"local-time\";\n\n// Initialize the cytoscape library and all of its extensions\nimport cytoscape from \"cytoscape\";\nimport elk from \"cytoscape-elk\";\nimport domNode from \"cytoscape-dom-node\";\nimport konva from \"konva\";\nimport edgeEditing from \"cytoscape-edge-editing\";\n\nimport { LicenseManager } from \"ag-grid-enterprise\";\n\n// We need to hardcode the license key here unfortunately, not much we can do about it\n// https://www.ag-grid.com/javascript-data-grid/licensing/#setting-the-license-key\nLicenseManager.setLicenseKey(\n \"Using_this_{AG_Grid}_Enterprise_key_{AG-058734}_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_legal@ag-grid.com___For_help_with_changing_this_key_please_contact_info@ag-grid.com___{SumIt_Software}_is_granted_a_{Single_Application}_Developer_License_for_the_application_{SumIt_Application}_only_for_{1}_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_working_on_{SumIt_Application}_need_to_be_licensed___{SumIt_Application}_has_been_granted_a_Deployment_License_Add-on_for_{1}_Production_Environment___This_key_works_with_{AG_Grid}_Enterprise_versions_released_before_{18_June_2025}____[v3]_[01]_MTc1MDIwMTIwMDAwMA==98e68128a50149df8120f79ff79f677f\",\n);\n\ncytoscape.use(elk);\n// @ts-ignore\ncytoscape.use(domNode);\n// @ts-ignore\ncytoscape.use(edgeEditing, konva);\n\n// ActionCable Channels\nimport \"~/channels\";\n\n// Stimulus controllers\nimport \"~/controllers\";\n\n// Jumpstart Pro & other Functionality\nimport.meta.glob(\"~/src/**/*\", { eager: true });\n\nActiveStorage.start();\nLocalTime.start();\n"],"names":["insertConfirmModal","message","element","button","confirmInput","confirmText","_a","description","_b","id","content","modal","commitButton","event","Turbo.config","dialog","resolve","_reject","_event","target","detail","file","progress","progressElement","error","response","getMetaValue","name","findElement","root","selector","removeElement","el","insertAfter","referenceNode","loadingIcon","account_code_select_controller","Controller","__publicField","options","item","escape","data","optGroupHeader","_data","_escape","values","TomSelect","className","templateName","whitelist","regex","iconNoAccountCodeGroupButton","innerButton","accountCodeGroupId","value","accountCode","iconNewButton","card","cardTurboSrcUrl","isEnabled","notCodedWithAccountCodeGroupIds","accountCodes","accountCodeGroups","groups","_query","callback","get","payload","optionGroups","optionGroup","search","score","lowerCaseName","lowerCaseAccountCodeGroupName","lowerCaseSearch","style","itemClasses","encodedString","tempDiv","control","isClosing","account_finder_controller","stream","Turbo.renderStreamMessage","account_number_generator_controller","queryParams","fullUrl","url","account_search_dropdown_controller","visibleItems","submitButton","searchTerms","hasVisibleItems","originalText","matches","accountTextElement","term","text","isVisible","mergedMatches","match","a","b","acc","curr","prev","result","lastIndex","string","div","account_select_for_intercompany_controller","select","selectedOption","number","account_select_for_ledger_controller","selectTarget","selectedLedgerId","selectedAccountId","query","account_template_select_controller","plugins","accounts","accountGroups","account","account_typeahead_search_controller","consumer","createConsumer","accounts_controller","action_modal_controller","buttonElement","topCard","turboFrame","frame","parentElement","actionClass","span","active_account_selector_controller","checkboxDisabled","clickedCheckbox","post","option","addepar_transaction_filter_controller","selectedAddeparField","addepar_transaction_filter_preview_controller","formData","showPreview","numberFormatter","percentageFormatter","dataTypeDefinitions","params","dateParts","formatDateForDisplay","date","CsvExporter","gridApi","filterModel","sortObject","sort","sortModel","filename","downloadPath","blob","formattedDate","accountCodeRenderer","tagRenderer","tags","realTags","tag","isGroupingByTag","parentEl","EMPTY_VALUE_FOR_SET_FILTER","convertFilterModel","from","to","key","convertFilterModelToServerSideFilterModel","convertServerSideFilterModelToFilterModel","createServerSideDatasource","datasourceUrl","setLoadingState","getCashFlowFilter","newRequest","groupKey","httpResponse","getFilterOptions","filterColumn","primaryKeyCreator","objectValueFormatter","advanced_register_controller","defaultNumberColDef","setFilterParams","setFilterColDefWithTreeParams","filterValue","cellValue","objectIds","thisGroupCol","additionalData","identifier","theButton","cardData","ledgerTransactionId","node","nodeIds","nodeId","uniqueSetIds","groupingByRows","savedState","filterModelToApply","createGrid","columnState","currentState","savedViewState","isFilterModelEqual","isEqual","isSortEqual","isColumnVisibilityEqual","isRowGroupEqual","isColumnOrderEqual","isRowGroupExpansionEqual","startDate","endDate","newFilterModel","oldFilterModel","dateColumns","dateFilterRemoved","colId","oldFilter","newFilter","dateFilterChanged","isFooter","breadcrumbIndentations","groupValue","field","newValue","_oldValue","ledgerEntryCountTarget","form","ledgerEntryIdInput","ledgerEntryIdInputEl","isLoading","attachment_delete_controller","destroy","_response","auto_click_controller","auto_reload_controller","Turbo.visit","auto_submit_controller","autohide_controller","bank_register_controller","targetStreams","searchQuery","selectedDateRange","targetStreamsQueryString","fullQueryString","newUrl","baseUrl","htmlUrl","Turbo.navigator","bank_transaction_controller","row","initialDebitsValue","initialCreditsValue","creditsTotal","remainingCreditsAmount","rowCreditsTarget","debitsTotal","remainingDebitsAmount","rowDebitsTarget","inputTargets","sum","input","accountsHaveValues","debitsAreNumbers","creditsAreNumbers","amount","isSectionHeader","isGroupHeader","isSectionFooter","isGroupFooter","accountCodeStyledCell","bgColor","fgColor","tagStyledCell","extraClasses","FlattenedAccountCellRenderer","metadata","accountCodeGroup","accountCodeName","template","accountSpan","_c","_params","AccountCellRenderer","tagGroup","child","_d","_e","GLAccountCellRenderer","isRootLevel","isAccountLevel","GLCellRenderer","formattedValue","link","linkField","NumberCellRenderer","tagStyledHeader","HeaderGroupRenderer","colDef","tagHeaderTemplate","isTextHeader","headerTemplate","consolidatedHeaderTemplate","spans","_key","consolidationMetadata","AccountCodeCellRenderer","TagCellRenderer","tagName","colorBg","colorFg","POSITIVE_VARIANCE_GROUPS","POSITIVE_VARIANCE_TOTALS","NEGATIVE_VARIANCE_GROUPS","NEGATIVE_VARIANCE_TOTALS","determineVarianceColor","budgetGroup","isPositiveGroup","isPercentage","period","periodData","valueForColor","getValueForVarianceColoring","isGoodVariance","budget","varianceAmount","getVarianceColorClass","ActualCellRenderer","url_path","BudgetCellRenderer","BaseVarianceRenderer","colorClass","VariancePercentageCellRenderer","hasBudget","VarianceAmountCellRenderer","defaultExcelExportParams","excelStyles","headerCells","header","ledgers","excelFileDetails","processCellForExcel","formatNameColumn","formatVariancePercentage","addIndentation","shouldShowNA","nestedLevel","nestedLevelClasses","budget_analysis_controller","classes","type","eDiv","order","nodeAValue","nodeBValue","level","defaultLevel","cellDataType","varianceColor","columns","showVarianceAmount","column","showVariancePercentage","remainingBudgetColumns","columnType","fieldName","columnDef","budget_analysis_datepicker_controller","StimulusFlatpickr","selectedDates","dateStr","_instance","x","budget_overview_controller","tippy","budget_table_sticky_controller","elementRect","activeElement","newScrollY","tableRect","cell","rowElement","columnIndex","leftPosition","i","tableContainer","containerRect","index","cloneCells","originalCells","shouldBeSticky","visible","scrollLeft","entries","entry","isSignificantlyObscured","isObscured","bulk_controller","bulk_update_ledger_entries_controller","cash_flow_defaults_controller","accountTypeSelect","accountType","cell_nav_controller","currentCell","currentColIndex","currentRowIndex","currentGroupIndex","currentGroupRowsCount","nextColIndex","nextRowIndex","nextGroupIndex","cellFromNextGroup","cellFromPrevGroup","nextCell","checkbox_select_all_controller","CheckboxSelectAll","checkboxes","childControllerElement","checkbox","parentCheckbox","allCheckboxes","allChecked","someChecked","parentControllerElement","parentController","checkbox_select_group_controller","currentTarget","groupId","checkboxGroup","click_hidden_controller","clipboard_controller","ClipboardJS","instance","compare_to_last_period_button_controller","hasOneLedger","ledger","isNotInterval","hasNoColTags","mergeEntities","isOnlyConsolidated","connected_transaction_controller","accountSelected","urlOrigin","connected_transactions_controller","selectedRows","selectedDestinationAccounts","accountSelect","connectedTransactionId","transactionTagId","count","selectedDestinationAccountBankTransactionIds","allSelectedRowsHaveDestinationAccounts","transactionForm","formActionUrl","searchParams","formatCurrencyValue","inputValue","patterns","cleanupPattern","numericValue","math.evaluate","numberValue","copy_amount_controller","counter_controller","currency_subtotal_controller","total","parseDateRangeOption","today","comparable","getQuarterStartMonth","datepicker_controller","formElement","currentMonth","currentYear","drag_controller","Sortable","patch","dropdown_with_tooltip_controller","Dropdown","isOpen","controllers","c","DropZoneController","createDropZone","dz","Dropzone","createDirectUploadController","DirectUploadController","source","createDirectUpload","attributes","xhr","controller","DirectUpload","dynamic_select_controller","enter_submit_controller","entity_graph_controller","cy","anchorElements","colorFunction","sourceArrowFunction","cytoscape","position","content_tag","visibility_tag","edgeEditor","positions","obj","bendPointPositions","edge","positionsArray","coordinatesArray","edgeEditorInstance","idx","y","success","indicator","entity_relationship_form_controller","shareInputs","totalShares","accumulator","currentValue","percentageReadOnlyElement","shareInput","percentage","finicity_controller","FinicityConnect","jsonResponse","connectUrl","connectEventHandlers","connectOptions","_previous","flowbite_modal_controller","targetEl","instanceOptions","Modal","frame_loader_controller","convertColToNumber","col","val","aggColumnValues","cols","getCheckboxValues","checkboxesIds","setOptionsCheckboxValue","setCheckboxValues","selectedCheckboxes","setSelectValues","selectedIds","getSelectValues","opt","addAutoLoadParamToUrl","calculatePercentChangeTotal","priorPeriodTotal","changeTotal","percentChangeTotal","validateDateSelected","context","parentNode","setDateAndAlertDisplay","optionsArray","alertsArray","alert","clearNotices","requestReportData","body","processReportDataResponse","hideErrorOverlay","showErrorOverlay","renderReportNotices","createErrorOverlay","overlay","overlayTemplate","generalNoticeElement","validateEntitySet","v","hasOption","optionName","getOptionState","numberValueGetter","columnField","updateBreadcrumb","reportTemplateId","arraysEqual","shouldRefreshGrouping","existingRowData","newRowData","existingDataMap","newRow","existingRow","prepareDateRangeOptions","addRelativeDatesToParams","parsedDates","getRelativeDates","loadDateRange","dateRangeTomSelect","loadDateInputs","saveReportTemplate","reportTemplateData","reportTemplateType","reportTemplateName","responseText","updateSavedReportTemplate","put","processSavedReport","savedReportId","requestSavedReport","savedReport","redirectToCorrectReport","loadSavedReportGridData","reportType","REPORT_LABELS","defaultExportParams","innerRenderer","breadcrumbArray","headerName","metadataEntries","defaultGLExportParams","buildIndentationStyles","styles","getClasses","getClassesForAccounts","getClassesForCells","isNumber","isCollapsedRow","headerRows","reportDate","entityNames","reportLabel","entitiesLabel","reportDateLabel","periodLabel","createCell","styleId","LoadingOverlay","NoRowsOverlay","general_ledger_controller","rowStyles","customClasses","baseClasses","baseClassesArray","agGridState","sessionReportOptions","accountTemplateIds","customEvent","fileName","showNoActivityAccountsValue","regularOptions","hasSkippedFirstLevel1Row","hasSeenFirstLevel1Row","columnKeys","e","showTags","showAccountCodes","showNoActivityAccountsCheckbox","ledgerSelect","selectedOptions","allLedgerCount","allLedgersSelected","ignore_transaction_controller","input_currency_formatter_controller","inputs","currentIndex","processSchemaOverridesResponse","responseData","template_overrides","entities","account_codes","accountOverrides","entityOverrides","entity","tagOverrides","accountCodeOverrides","journal_entry_importer_controller","schemaOverrides","oneschemaImporter","processedData","ledger_entries_controller","_element","targetInput","rowNumber","counter","isCreditUpdate","rowDebitInput","rowCreditInput","ledger_name_controller","ledger_select_controller","controlClasses","maxItems","ledger_transaction_controller","toRemove","toAdd","ledger_transaction_notices_controller","accountIds","effectiveDate","effectiveDateWas","hasClosedEntry","closeDateString","closeDate","fromNullToOutsideClosedPeriod","fromOutsideToOutsideClosedPeriod","mapping_manager_importer_controller","overrides","picklistOptions","records","record","prefixId","nested_addepar_transaction_filter_controller","NestedForm","elementClone","nonDeletedRows","nested_form_controller","nested_ledger_entry_controller","ledgerId","nested_rule_conditions_controller","titleContainers","net_cash_flow_toggle_controller","Toggle","notifications_controller","ids","optional_object_controller","divFromTemplate","ordinal_controller","ownership_to_partnership_controller","inputElements","errorMessageContainer","entityIdsAndNamesForOptions","selectedEntityId","ownershipRelationship","entityId","entityName","ownerships","dataTarget","targetNode","selected","isSelected","r","payable_controller","payeeName","invoiceIdentifier","payeeNamePrefix","randomHexString","payableLineItemsSum","differenceAmount","label","formattedDifferenceAmount","payable_line_items_controller","lineItemIndexes","lineItemIds","lineItem","toggleButton","buttonTargets","removeMiddleBorder","totalButtons","payable_type_controller","payment_terms_controller","netDays","invoiceDate","daysToAdd","netDate","dateString","parts","paymentTermsDays","INVALID_LINK_TOKEN_ERROR_CODE","LINK_TOKEN_LOCAL_STORAGE_KEY","OAUTH_STATE_ID_PARAM","plaid_controller","publicToken","err","_metadata","linkTokenData","oauthStateIdParam","plaid_update_controller","_publicToken","_err","radio_select_all_controller","radio","reconciliation_checkbox_select_all_controller","isChecked","ledgerEntryIds","reconciliation_controller","removable_controller","reporting_controller","currentPeriodTotal","accountCodeIds","colTagIds","rowTagIds","groupByAccountCodes","groupByTags","savedOptions","showZeroBalanceAccountsValue","showInactiveAccountsValue","reportOptions","rowNode","childrenAfterGroup","cellRenderer","originalRowData","ledgerSelectValues","container","toggle","enabled","columnDefData","childrenLevel","isColTaggedReport","columnDefs","totalCol","valueA","valueB","nodeA","nodeB","_isInverted","accountOrder","nodeAAccountNumberAndName","nodeBAccountNumberAndName","showZeroBalanceAccountsCheckbox","showInactiveAccountsCheckbox","reporting_datepicker_controller","reporting_row_options_controller","panel","activeButton","inactiveButton","showPanel","hidePanel","rule_preview_controller","conditions","condition","descriptionOperatorTarget","ledgerSelectedOptions","acccountSelectedOption","conditionTargetValue","valuesTargets","saved_register_view_controller","saving_message_controller","scroll_to_controller","select_all_top_checkbox_controller","select_controller","select_toggle_controller","startingValue","selectedValue","section","showWhens","showWhen","slideover_content_controller","contentId","sticky_dropdown_controller","sticky_table_controller","direction","columnTargets","cumulativeWidth","rows","positionIndex","absolutePosition","rowIndex","cells","positionIndexFromRight","cellIndex","stimulus_tooltip_controller","tooltip","submit_controller","redirectUrl","subtype_dropdown_controller","selectedType","selectedSubtype","sum_it_color_picker_controller","__privateAdd","_sum_it_color_picker_controller_instances","__privateMethod","currentlyCheckedLabel_fn","highlightSelectedColor_fn","inputRadioId","labelBorder","colorPickerPreview","colorPickerPreviewText","labelColor","labelText","currentlyChecked","table_controller","delegate","targetHasText","tag_select_controller","_values","optionId","iconNoTagGroupButton","tagGroupId","selectedTagGroupIds","notTaggedWithTagGroupIds","groupIds","wasDisabled","tagGroups","lowerCaseTagGroupName","tax_classification_select_controller","template_controller","toggle_all_controller","toggleable","toggle_class_controller","toggleClass","isAddingClass","shouldAddClass","toggle_controller","toggle_disable_controller","checkboxToDisable","dependentInput","toggle_permissions_controller","toggle_readonly_controller","transaction_payables_match_controller","payableIdInput","payableIdInputEl","transaction_transfer_controller","destinationDescription","destinationDescriptionTransactionId","destinationDescriptionValue","divElement","textareaElement","accountCodeSelect","accountCodeSelectTransactionId","accountCodeTomSelect","tagSelect","tagSelectTransactionId","tagTomSelect","intercompanyAccountSelect","intercompanyAccountSelectTransactionId","intercompanyAccountSelectLedgerId","submitId","unsaved_changes_controller","config","uploaded_transactions_controller","url_history_handler_controller","vendor_select_controller","vendor","vendors","registerControllers","application","Tabs","Slideover","Flowbite","LicenseManager","elk","domNode","edgeEditing","konva","ActiveStorage.start","LocalTime"],"mappings":"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"}