refine-rails 2.13.7 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"refine-stimulus.umd.js","sources":["../../../node_modules/@hotwired/stimulus-webpack-helpers/dist/stimulus-webpack-helpers.js","../../javascript/controllers/refine/server-refresh-controller.js","../../javascript/controllers/refine/add-controller.js","../../javascript/controllers/refine/criterion-form-controller.js","../../javascript/controllers/refine/defaults-controller.js","../../javascript/controllers/refine/delete-controller.js","../../javascript/controllers/refine/filter-pills-controller.js","../../javascript/controllers/refine/popup-controller.js","../../javascript/controllers/refine/modal-controller.js","../../javascript/controllers/refine/search-filter-controller.js","../../javascript/refine/helpers/index.js","../../javascript/controllers/refine/state-controller.js","../../javascript/controllers/refine/stored-filter-controller.js","../../javascript/controllers/refine/submit-form-controller.js","../../javascript/controllers/refine/toggle-controller.js","../../javascript/controllers/refine/turbo-stream-form-controller.js","../../javascript/controllers/refine/turbo-stream-link-controller.js","../../javascript/controllers/refine/typeahead-list-controller.js","../../javascript/controllers/refine/update-controller.js","../../javascript/controllers/refine/date-controller.js","../../javascript/controllers/refine/inline-advanced-modal-controller.js","../../javascript/controllers/fields/shoelace/tab-group-controller.js","../../javascript/controllers/index.js"],"sourcesContent":["/*\nStimulus Webpack Helpers 1.0.0\nCopyright © 2021 Basecamp, LLC\n */\nfunction definitionsFromContext(context) {\n return context.keys()\n .map((key) => definitionForModuleWithContextAndKey(context, key))\n .filter((value) => value);\n}\nfunction definitionForModuleWithContextAndKey(context, key) {\n const identifier = identifierForContextKey(key);\n if (identifier) {\n return definitionForModuleAndIdentifier(context(key), identifier);\n }\n}\nfunction definitionForModuleAndIdentifier(module, identifier) {\n const controllerConstructor = module.default;\n if (typeof controllerConstructor == \"function\") {\n return { identifier, controllerConstructor };\n }\n}\nfunction identifierForContextKey(key) {\n const logicalName = (key.match(/^(?:\\.\\/)?(.+)(?:[_-]controller\\..+?)$/) || [])[1];\n if (logicalName) {\n return logicalName.replace(/_/g, \"-\").replace(/\\//g, \"--\");\n }\n}\n\nexport { definitionForModuleAndIdentifier, definitionForModuleWithContextAndKey, definitionsFromContext, identifierForContextKey };\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n\n// Base class for controllers that reload form content from the server\nexport default class extends Controller {\n connect() {\n this.state.finishUpdate()\n }\n\n get state() {\n let currentElement = this.element\n\n while(currentElement !== document.body) {\n if (currentElement.matches('[data-controller~=\"refine--state\"]'))\n return this.application.getControllerForElementAndIdentifier(currentElement, 'refine--state')\n else {\n currentElement = currentElement.parentNode\n }\n }\n\n return null\n }\n\n async refreshFromServer(options = {}) {\n const { includeErrors } = options\n this.state.startUpdate()\n const request = new FetchRequest(\n \"GET\",\n this.state.refreshUrlValue,\n {\n responseKind: \"turbo-stream\",\n query: {\n \"refine_filters_builder[filter_class]\": this.state.filterName,\n \"refine_filters_builder[blueprint_json]\": JSON.stringify(this.state.blueprint),\n \"refine_filters_builder[client_id]\": this.state.clientIdValue,\n include_errors: !!includeErrors\n }\n }\n )\n await request.perform()\n }\n}\n","import ServerRefreshController from './server-refresh-controller'\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends ServerRefreshController {\n static values = {\n previousCriterionId: Number,\n }\n\n async criterion() {\n const isValid = await this.validateBlueprint()\n if (isValid) {\n this.state.addCriterion(this.previousCriterionIdValue)\n }\n this.refreshFromServer({includeErrors: !isValid})\n }\n\n async group() {\n const isValid = await this.validateBlueprint()\n if (isValid) {\n this.state.addGroup()\n }\n this.refreshFromServer({includeErrors: !isValid})\n }\n\n async validateBlueprint(blueprint) {\n const { state } = this\n\n const request = new FetchRequest(\n \"GET\",\n this.state.validateBlueprintUrlValue,\n {\n query: {\n \"refine_filters_builder[filter_class]\": this.state.filterName,\n \"refine_filters_builder[blueprint_json]\": JSON.stringify(this.state.blueprint),\n \"refine_filters_builder[client_id]\": this.state.clientIdValue\n }\n }\n )\n const response = await request.perform()\n return response.ok\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n This controller handles criteria forms\n (refine/inline/criteria/new|edit)\n*/\nexport default class extends Controller {\n static values = {\n url: String,\n formId: String\n }\n\n async refresh(_event) {\n // update the url with params from the form\n const formElement = document.getElementById(this.formIdValue)\n const formData = new FormData(formElement)\n\n const request = new FetchRequest(\n \"GET\",\n this.urlValue,\n {\n query: formData,\n responseKind: \"turbo-stream\"\n }\n )\n const response = await request.perform()\n }\n\n\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static values = {\n criterionId: Number,\n input: Object,\n };\n\n connect() {\n this.state = this.getStateController()\n\n this.state.updateInput(\n this.criterionIdValue,\n this.inputValue,\n );\n }\n\n getStateController() {\n let currentElement = this.element\n\n while(currentElement !== document.body) {\n const controller = this.application.getControllerForElementAndIdentifier(currentElement, 'refine--state')\n if (controller) {\n return controller\n } else {\n currentElement = currentElement.parentNode\n }\n }\n\n return null\n }\n}\n","import ServerRefreshController from './server-refresh-controller';\n\nexport default class extends ServerRefreshController {\n static values = {\n criterionId: Number,\n }\n\n criterion() {\n const { state, criterionIdValue } = this;\n state.deleteCriterion(criterionIdValue);\n this.refreshFromServer()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends Controller {\n static values = {\n submitUrl: String\n }\n\n connect() {\n const urlParams = new URLSearchParams(window.location.search)\n this.existingParams = urlParams\n this.existingParams.delete('stable_id')\n }\n\n delete(event) {\n const { criterionId } = event.currentTarget.dataset\n var index = parseInt(criterionId)\n this.stateController.deleteCriterion(index)\n this.reloadPage()\n }\n\n async reloadPage() {\n const {blueprint} = this.stateController\n const request = new FetchRequest(\n \"POST\",\n this.submitUrlValue,\n {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({\n refine_filters_builder: {\n filter_class: this.stateController.filterName,\n blueprint_json: JSON.stringify(blueprint),\n client_id: this.stateController.clientIdValue\n }\n })\n }\n )\n await request.perform()\n }\n\n redirectToStableId(stableId) {\n const params = new URLSearchParams()\n if (stableId) {\n params.append('stable_id', stableId)\n }\n const allParams = new URLSearchParams({\n ...Object.fromEntries(this.existingParams),\n ...Object.fromEntries(params),\n }).toString()\n const url = `${window.location.pathname}?${allParams}`\n\n history.pushState({}, document.title, url)\n window.location.reload()\n }\n\n get stateController() {\n return this.element.refineStateController\n }\n\n get stabilizeFilterController() {\n return this.element.stabilizeFilterController\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { useClickOutside } from 'stimulus-use'\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"frame\"]\n\n static values = {\n src: String,\n isOpen: {type: Boolean, default: false}\n }\n\n connect() {\n useClickOutside(this)\n this.boundHandleKeyUp = this.handleKeyUp.bind(this)\n document.addEventListener(\"keyup\", this.boundHandleKeyUp)\n }\n\n disconnect() {\n document.removeEventListener(\"keyup\", this.boundHandleKeyUp)\n }\n\n show(event) {\n event.preventDefault()\n this.frameTarget.src = this.srcValue;\n this.isOpenValue = true\n }\n\n hide(event) {\n if (this.isOpenValue) {\n event?.preventDefault()\n event?.stopPropagation()\n this.frameTarget.innerHTML = \"\";\n this.isOpenValue = false\n }\n }\n\n clickOutside(event) {\n this.hide(event)\n }\n\n handleKeyUp(event) {\n if (event.key === \"Escape\" || event.key === \"Esc\") {\n this.hide(event)\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { useClickOutside } from 'stimulus-use'\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"frame\"]\n\n static values = {\n src: String,\n isOpen: {type: Boolean, default: false}\n }\n\n connect() {\n useClickOutside(this)\n }\n\n disconnect() {\n }\n\n open(event) {\n event.preventDefault()\n this.frameTarget.src = this.srcValue;\n this.isOpenValue = true\n }\n\n close(event) {\n if (this.isOpenValue) {\n event?.preventDefault()\n this.frameTarget.innerHTML = \"\";\n this.isOpenValue = false\n }\n }\n\n clickOutside(event) {\n this.close(event)\n }\n\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends Controller {\n static values = {\n submitUrl: String\n }\n\n\n search(event) {\n event.preventDefault()\n this.submitFilter()\n document.activeElement.blur()\n }\n\n async submitFilter() {\n const {blueprint} = this.stateController\n const request = new FetchRequest(\n \"POST\",\n this.submitUrlValue,\n {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({\n refine_filters_builder: {\n filter_class: this.stateController.filterName,\n blueprint_json: JSON.stringify(blueprint),\n client_id: this.stateController.clientIdValue\n }\n })\n }\n )\n await request.perform()\n }\n\n get stateController() {\n return this\n .element\n .querySelector('[data-controller~=\"refine--state\"]')\n .refineStateController\n }\n\n loadResults({detail: {url}}) {\n console.log(\"filter submit success\")\n if (window.Turbo) {\n window.Turbo.visit(url)\n } else {\n window.location.href = url\n }\n }\n}\n","// Polyfill for custom events in IE9-11\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill\n;(function () {\n if (typeof window.CustomEvent === 'function') return false\n\n function CustomEvent(event, params) {\n params = params || { bubbles: false, cancelable: false, detail: undefined }\n var evt = document.createEvent('CustomEvent')\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n return evt\n }\n\n CustomEvent.prototype = window.Event.prototype\n\n window.CustomEvent = CustomEvent\n\n // eslint expects a return here\n return true\n})()\n\nexport const filterStabilizedEvent = (element, stableId, filterName) => {\n const event = new CustomEvent('filter-stabilized', {\n bubbles: true,\n cancelable: true,\n detail: {\n stableId,\n filterName,\n },\n })\n element.dispatchEvent(event)\n}\n\nexport const filterUnstableEvent = (blueprint) => {\n const event = new CustomEvent('filter-unstable', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const filterInvalidEvent = ({blueprint, errors}) => {\n const event = new CustomEvent('filter-invalid', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n errors,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const filterStoredEvent = (storedFilterId) => {\n const event = new CustomEvent('filter-stored', {\n bubbles: true,\n cancelable: true,\n detail: {\n storedFilterId,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const blueprintUpdatedEvent = (element, {blueprint, formId}) => {\n const event = new CustomEvent('blueprint-updated', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n formId\n },\n })\n element.dispatchEvent(event)\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { delegate, abnegate } from 'jquery-events-to-dom-events'\nimport { blueprintUpdatedEvent } from '../../refine/helpers'\nimport { isEqual } from 'lodash'\n\nconst criterion = (id, depth, condition) => {\n const component = condition?.component\n const meta = condition?.meta || { clauses: [], options: {}}\n const refinements = condition?.refinements || []\n const { clauses, options } = meta\n let selected\n if (component === 'option-condition') {\n selected = options[0] ? [options[0].id] : []\n } else {\n selected = undefined\n }\n // Set newInput based on component\n\n let newInput = {\n clause: clauses[0]?.id,\n selected: selected,\n }\n\n // If refinements are present, add to input array\n refinements.forEach((refinement) => {\n const { meta, component } = refinement\n const { clauses, options } = meta\n let selected\n if (component === 'option-condition') {\n selected = options[0] ? [options[0].id] : []\n } else {\n selected = undefined\n }\n newInput[refinement.id] = {\n clause: clauses[0].id,\n selected: selected,\n }\n })\n\n return {\n depth,\n type: 'criterion',\n condition_id: id,\n input: newInput,\n }\n}\n\nconst or = function (depth) {\n depth = depth === undefined ? 0 : depth\n return {\n depth,\n type: 'conjunction',\n word: 'or',\n }\n}\n\nconst and = function (depth) {\n depth = depth === undefined ? 1 : depth\n return {\n depth,\n type: 'conjunction',\n word: 'and',\n }\n}\nexport default class extends Controller {\n static values = {\n blueprint: Array,\n conditions: Array,\n className: String,\n refreshUrl: String,\n clientId: String,\n validateBlueprintUrl: String,\n defaultConditionId: String\n }\n static targets = ['loading']\n\n\n connect() {\n // for select2 jquery events and datepicker\n this.element.refineStateController = this\n this.changeDelegate = delegate('change', ['event', 'picker'])\n this.blueprint = this.blueprintValue\n this.conditions = this.conditionsValue\n this.filterName = this.classNameValue\n this.conditionsLookup = this.conditions.reduce((lookup, condition) => {\n lookup[condition.id] = condition\n return lookup\n }, {})\n this.loadingTimeout = null\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n disconnect() {\n abnegate('change', this.changeDelegate)\n }\n\n startUpdate() {\n if (this.loadingTimeout) {\n window.clearTimeout(this.loadingTimeout)\n }\n // only show the loading overlay if it's taking a long time\n // to render the updates\n this.loadingTimeout = window.setTimeout(() => {\n this.loadingTarget.classList.remove('hidden')\n }, 1000)\n }\n\n finishUpdate() {\n if (this.loadingTimeout) {\n window.clearTimeout(this.loadingTimeout)\n }\n this.loadingTarget.classList.add('hidden')\n }\n\n conditionConfigFor(conditionId) {\n return this.conditionsLookup[conditionId]\n }\n\n addGroup() {\n const { blueprint, conditions } = this\n const condition = ( conditions.find(c => c.id == this.defaultConditionIdValue) || conditions[0] )\n const { meta } = condition\n\n if (this.blueprint.length > 0) {\n this.blueprint.push(or())\n }\n this.blueprint.push(criterion(condition.id, 1, condition))\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n addCriterion(previousCriterionId) {\n const { blueprint, conditions } = this\n const condition = ( conditions.find(c => c.id == this.defaultConditionIdValue) || conditions[0] )\n const { meta } = condition\n blueprint.splice(previousCriterionId + 1, 0, and(), criterion(condition.id, 1, condition))\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n deleteCriterion(criterionId) {\n /**\n To support 'groups' there is some complicated logic for deleting criterion.\n\n Imagine this simplified blueprint: [eq, and, sw, or, eq]\n\n User clicks to delete the last eq. We also have to delete the preceding or\n otherwise we're left with a hanging empty group\n\n What if the user deletes the sw? We have to clean up the preceding and.\n\n Imagine another scenario: [eq or sw and ew]\n Now we delete the first eq but this time we need to clean up the or.\n\n These conditionals cover these cases.\n **/\n const { blueprint } = this\n const previous = blueprint[criterionId - 1]\n const next = blueprint[criterionId + 1]\n\n const nextIsOr = next && next.word === 'or'\n const previousIsOr = previous && previous.word === 'or'\n\n const nextIsRightParen = nextIsOr || !next\n const previousIsLeftParen = previousIsOr || !previous\n\n const isFirstInGroup = previousIsLeftParen && !nextIsRightParen\n const isLastInGroup = previousIsLeftParen && nextIsRightParen\n const isLastCriterion = !previous && !next\n\n if (isLastCriterion) {\n this.blueprint = []\n } else if (isLastInGroup && previousIsOr) {\n blueprint.splice(criterionId - 1, 2)\n } else if (isLastInGroup && !previous) {\n blueprint.splice(criterionId, 2)\n } else if (isFirstInGroup) {\n blueprint.splice(criterionId, 2)\n } else {\n blueprint.splice(criterionId - 1, 2)\n }\n\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n /*\n Updates a criterion in the blueprint\n Returns true if an update was actually performed, or false if no-op\n */\n replaceCriterion(criterionId, conditionId, condition) {\n const criterionRow = this.blueprint[criterionId]\n if (criterionRow.type !== 'criterion') {\n throw new Error(\n `You can't call updateConditionId on a non-criterion type. Trying to update ${JSON.stringify(criterion)}`\n )\n }\n const existingCriterion = this.blueprint[criterionId]\n const newCriterion = criterion(conditionId, criterionRow.depth, condition)\n if (isEqual(existingCriterion, newCriterion)) {\n return false\n } else {\n this.blueprint[criterionId] = newCriterion\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n return true\n }\n }\n\n updateInput(criterionId, input, inputId) {\n // Input id is an array of hash keys that define the path for this input such as [\"input\", \"date_refinement\"]\n const { blueprint } = this\n const criterion = blueprint[criterionId]\n inputId = inputId || 'input'\n const blueprintPath = inputId.split(', ')\n // If the inputId contains more than one element, add input at appropriate depth\n if (blueprintPath.length > 1) {\n criterion[blueprintPath[0]][blueprintPath[1]] = { ...criterion[blueprintPath[0]][blueprintPath[1]], ...input }\n } else {\n criterion[inputId] = { ...criterion[inputId], ...input }\n }\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { filterStoredEvent } from '../../refine/helpers'\n\nexport default class extends Controller {\n static targets = ['blueprintField']\n static values = { formId: String, stateDomId: String }\n\n connect() {\n const stateController = document\n .getElementById(this.stateDomIdValue)\n .refineStateController\n this.blueprintFieldTarget.value = JSON.stringify(stateController.blueprint)\n console.log(\"connect\", this.blueprintFieldTarget.value)\n }\n\n updateBlueprintField(event) {\n if (event.detail.formId != this.formIdValue) { return null }\n const { detail } = event\n const { blueprint } = detail\n this.blueprintFieldTarget.value = JSON.stringify(blueprint)\n console.log(\"update blueprint\", this.blueprintFieldTarget.value)\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n submit(event) {\n event.preventDefault()\n this.element.requestSubmit()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"content\"]\n\n toggle(_event) {\n this.contentTargets.forEach(node => {\n node.toggleAttribute(\"hidden\")\n })\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n attach to a form element to have it submit to a turbo-stream endpoint\n\n <form action=\"/contacts\" data-controller=\"refine--turbo-stream-form\" data-action=\"submit->refine--turbo-stream-form#submit\">\n\n Turbo is supposed to handle this natively but we're seeing issues when the form is inside an iframe\n*/\nexport default class extends Controller {\n async submit(event) {\n event.preventDefault()\n const request = new FetchRequest(\n (this.element.method || \"POST\"),\n this.element.action,\n {\n responseKind: \"turbo-stream\",\n body: new FormData(this.element)\n }\n )\n await request.perform()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n attach to a link element to have it request turbo stream responses\n\n <a href=\"/contacts\" data-controller=\"refine--turbo-stream-link\" data-action=\"refine--turbo-stream-link#get\">Click me</a>\n\n Turbo is supposed to handle this natively with data-turbo-stream but we're\n seeing issues using that attribute inside iframes\n*/\nexport default class extends Controller {\n async visit(event) {\n event.preventDefault()\n const request = new FetchRequest(\n (this.element.dataset.turboMethod || \"GET\"),\n this.element.href,\n {\n responseKind: \"turbo-stream\",\n }\n )\n await request.perform()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n\n static targets = ['listItem', 'category', 'recommended']\n\n filter(event) {\n const query = event.currentTarget.value.toLowerCase()\n this.handleFilter(query) \n }\n\n clearSearch() {\n this.handleFilter('')\n }\n\n handleFilter(query) {\n const visibleCategories = new Set()\n\n // hide / show listItem links that match the query and note which\n // categories should be visible\n this.listItemTargets.forEach(listItemNode => {\n const listItemName = listItemNode.dataset.listItemValue.toLowerCase()\n if (listItemName.includes(query)) {\n listItemNode.hidden = false\n visibleCategories.add(listItemNode.dataset.category)\n } else {\n listItemNode.hidden = true\n }\n })\n\n this.recommendedTargets.forEach(recommendedNode => {\n (query !== '' && visibleCategories.size === 0) ? recommendedNode.hidden = true : recommendedNode.hidden = false\n })\n\n // hide / show category headers that have visible listItems\n this.categoryTargets.forEach(categoryNode => {\n const categoryName = categoryNode.innerHTML\n if (visibleCategories.has(categoryName)) {\n categoryNode.hidden = false\n } else {\n categoryNode.hidden = true\n }\n })\n }\n}\n","import ServerRefreshController from './server-refresh-controller'\nimport { debounce } from 'lodash'\n\nexport default class extends ServerRefreshController {\n static values = {\n criterionId: Number,\n }\n\n initialize() {\n this.updateBlueprint = debounce((event, value, inputKey) => {\n this.value(event, value, inputKey)\n }, 500)\n }\n\n refinedFilter(event) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n\n state.updateInput(\n criterionIdValue,\n {\n id: event.target.value,\n },\n inputId\n )\n this.refreshFromServer()\n }\n\n clause(event) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n state.updateInput(\n criterionIdValue,\n {\n clause: event.target.value,\n },\n inputId\n )\n this.refreshFromServer()\n }\n\n selected(event) {\n const { target: select } = event\n const options = Array.prototype.slice.call(select.options)\n const selectedOptions = options.filter((option) => option.selected)\n const selected = selectedOptions.map((option) => option.value)\n this.value(event, selected, 'selected')\n }\n\n value(event, value, inputKey) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n inputKey = inputKey || dataset.inputKey || 'value'\n value = value || event.target.value\n if(typeof value === 'string')\n value = value.trim()\n state.updateInput(\n criterionIdValue,\n {\n [inputKey]: value,\n },\n inputId\n )\n }\n\n condition(event) {\n const { criterionIdValue, state } = this\n const element = event.target\n let newConditionId = element.value\n if (!newConditionId) newConditionId = element.querySelector('select').value \n const config = this.state.conditionConfigFor(newConditionId)\n const updatePerformed = state.replaceCriterion(criterionIdValue, newConditionId, config)\n if (updatePerformed) {\n this.refreshFromServer()\n }\n }\n\n // Prevent form submission when hitting enter in a text box\n cancelEnter(event) {\n if (event.code === \"Enter\") {\n event.preventDefault()\n event.stopPropagation()\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport moment from 'moment'\nrequire('daterangepicker/daterangepicker.css')\n\n// requires jQuery, moment, might want to consider a vanilla JS alternative\nimport $ from 'jquery' // ensure jquery is loaded before daterangepicker\nimport 'daterangepicker'\n\nexport default class extends Controller {\n static targets = [\n 'field',\n 'hiddenField',\n 'clearButton',\n ]\n\n static values = {\n includeTime: Boolean,\n futureOnly: Boolean,\n drops: String,\n inline: Boolean,\n dateFormat: String,\n timeFormat: String,\n isAmPm: Boolean,\n locale: { type: String, default: 'en' },\n datetimeFormat: { type: String, default: 'MM/DD/YYYY h:mm A' },\n pickerLocale: { type: Object, default: {} },\n }\n\n connect() {\n this.initPluginInstance()\n }\n\n disconnect() {\n this.teardownPluginInstance()\n }\n\n clearDate(event) {\n // don't submit the form, unless it originated from the cancel/clear button\n event.preventDefault()\n\n window.$(this.fieldTarget).val('')\n\n this.dispatch('value-cleared')\n }\n\n applyDateToField(event, picker) {\n const format = this.includeTimeValue ? this.timeFormatValue : this.dateFormatValue\n\n const momentVal = picker\n ? moment(picker.startDate.toISOString())\n : moment(this.fieldTarget.value, 'YYYY-MM-DDTHH:mm').format('YYYY-MM-DDTHH:mm')\n const displayVal = momentVal.format(format)\n const dataVal = this.includeTimeValue ? momentVal.toISOString(true) : momentVal.format('YYYY-MM-DD')\n\n this.fieldTarget.value = displayVal\n this.hiddenFieldTarget.value = dataVal\n // bubble up a change event when the input is updated for other listeners\n window.$(this.fieldTarget).trigger('change', picker)\n\n // emit native change event\n this.hiddenFieldTarget.dispatchEvent(new Event('change', { detail: picker, bubbles: true }))\n }\n\n initPluginInstance() {\n const localeValues = this.pickerLocaleValue\n const isAmPm = this.isAmPmValue\n localeValues['format'] = this.includeTimeValue ? this.timeFormatValue : this.dateFormatValue\n\n window.$(this.fieldTarget).daterangepicker({\n singleDatePicker: true,\n timePicker: this.includeTimeValue,\n timePickerIncrement: 5,\n autoUpdateInput: false,\n autoApply: true,\n minDate: this.futureOnlyValue ? new Date() : false,\n locale: localeValues,\n parentEl: $(this.element),\n drops: this.dropsValue ? this.dropsValue : 'down',\n timePicker24Hour: !isAmPm,\n })\n\n window.$(this.fieldTarget).on('apply.daterangepicker', this.applyDateToField.bind(this))\n window.$(this.fieldTarget).on('cancel.daterangepicker', this.clearDate.bind(this))\n window.$(this.fieldTarget).on('showCalendar.daterangepicker', this.showCalendar.bind(this))\n\n this.pluginMainEl = this.fieldTarget\n this.plugin = $(this.pluginMainEl).data('daterangepicker') // weird\n\n if (this.inlineValue) {\n this.element.classList.add('date-input--inline')\n }\n\n }\n \n teardownPluginInstance() {\n if (this.plugin === undefined) {\n return\n }\n\n $(this.pluginMainEl).off('apply.daterangepicker')\n $(this.pluginMainEl).off('cancel.daterangepicker')\n $(this.pluginMainEl).off('showCalendar.daterangepicker')\n\n // revert to original markup, remove any event listeners\n this.plugin.remove()\n\n }\n\n showCalendar() {\n this.dispatch('show-calendar')\n }\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n\n static targets = ['searchBarInput', 'categoryListItem', 'categoryBlockItem', 'categoryShortcutItem', 'scrollContainer']\n\n connect() {\n this.observer = new IntersectionObserver(\n this.handleIntersection.bind(this), {\n root: this.scrollContainerTarget,\n threshold: 1.0,\n rootMargin: '0px 0px -80% 0px'\n }\n )\n\n this.bottomObserver = new IntersectionObserver(\n this.handleBottomIntersection.bind(this), {\n root: this.scrollContainerTarget,\n threshold: 1.0\n }\n )\n\n this.shouldHighlightCategories = true;\n this.handleHighlightTimeout = null;\n this.bottomMarker = document.getElementById('refine--picker-bottom-marker');\n\n this.categoryListItemTargets.forEach(item => this.observer.observe(item))\n this.bottomObserver.observe(this.bottomMarker)\n }\n\n disconnect() {\n this.bottomObserver.disconnect()\n this.observer.disconnect()\n }\n\n handleIntersection(entries) {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target !== this.bottomMarker) {\n if(entry.intersectionRatio == 1) {\n this.highlightCategory(entry.target.dataset.categoryListItemValue)\n }\n }\n })\n }\n\n handleBottomIntersection(entries) {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target === this.bottomMarker) {\n this.highlightCategory(this.categoryListItemTargets[this.categoryListItemTargets.length - 1].dataset.categoryListItemValue)\n }\n })\n }\n \n\n highlightCategory(categoryName, force=false) {\n if(this.shouldHighlightCategories || force) {\n this.categoryShortcutItemTargets.forEach(item => {\n if(item.dataset.inlineAdvancedModalValue === categoryName) {\n item.classList.add('active')\n } else {\n item.classList.remove('active')\n }\n })\n }\n }\n\n showSearchBar() {\n this.searchBarInputTarget.hidden = false\n }\n\n hideSearchBar() {\n this.searchBarInputTarget.hidden = true\n }\n\n findCategoryElementByName(categoryName) {\n // Use the find method to locate the target with the specified attribute value\n return this.categoryListItemTargets.find(item => item.dataset.categoryListItemValue === categoryName)\n }\n\n clearSelection() {\n this.debounceScrollHighlights();\n this.categoryShortcutItemTargets.forEach((item) => {\n item.classList.remove('active')\n })\n }\n\n clearSearch() {\n if (this.searchBarInputTarget.querySelector(\"input\")) {\n this.searchBarInputTarget.querySelector(\"input\").value = ''\n }\n }\n\n scrollToCategory(event) {\n const categoryName = event.target.dataset.inlineAdvancedModalValue\n const categoryElement = this.findCategoryElementByName(categoryName)\n if(categoryElement) {\n this.shouldHighlightCategories = false;\n categoryElement.scrollIntoView({\n behavior: \"smooth\",\n block: \"start\",\n inline: \"nearest\"\n })\n setTimeout(() => {\n this.shouldHighlightCategories = true;\n this.highlightCategory(categoryName, true);\n }, 750);\n }\n }\n\n debounceScrollHighlights() {\n this.shouldHighlightCategories = false;\n clearTimeout(this.handleHighlightTimeout);\n this.handleHighlightTimeout = setTimeout(() => {\n this.shouldHighlightCategories = true;\n }, 1000)\n }\n \n}\n","// to be used with sl-tab-group\nimport { Controller } from \"@hotwired/stimulus\"\n\n// This controller is used to handle the tab group component\n// @see https://shoelace.style/components/tab-group\n// @param keepScrollPosition [Boolean] - If true, the scroll position will be kept when changing tabs\n// @usage <div data-controller=\"shoelace--tab-group\" data-shoelace--tab-group-keep-scroll-position-value=\"true\">\n\nexport default class extends Controller {\n static values = {\n keepScrollPosition: { type: Boolean, default: false },\n }\n\n connect() {\n this.currentScrollYPosition = 0\n this.navigateToTab = this.navigateToTab.bind(this)\n this.handleTabShow = this.handleTabShow.bind(this)\n\n this.navigateToTab()\n\n document.addEventListener('turbo:load', this.navigateToTab)\n this.element.addEventListener('sl-tab-show', this.handleTabShow)\n }\n\n disconnect() {\n document.removeEventListener('turbo:load', this.navigateToTab)\n this.element.removeEventListener('sl-tab-show', this.handleTabShow)\n }\n\n handleTabShow(event) {\n this.setLocationHash(event)\n\n if (this.keepScrollPositionValue) {\n this.handleTabChange()\n }\n }\n\n setLocationHash(event) {\n window.location.hash = event.detail.name\n }\n\n navigateToTab() {\n let hash = window.location.hash.toString()\n if (hash) {\n this.element.show(hash.slice(1))\n } else {\n /*\n * Turbo doesn't currently support hashes on redirects (see https://github.com/hotwired/turbo/issues/825)\n * so we've created a workaround. Pass `redirect_anchor` as a query param, and the component will convert\n * it to a hash and delete the query param. e.g. `some_url?redirect_anchor=store_upsells`\n */\n const params = new URLSearchParams(window.location.search)\n const redirectedHashParam = params.get('redirect_anchor')\n if (redirectedHashParam) {\n params.delete('redirect_anchor')\n let newParams = params.toString()\n window.history.replaceState(\n null,\n '',\n [window.location.pathname, newParams ? `?${newParams}` : '', '#', redirectedHashParam].join('')\n )\n }\n }\n }\n\n handleTabChange() {\n this.currentScrollYPosition = window.scrollY\n }\n\n /**\n * Programmatically reveal a sl-tab-panel via action params.\n * @see Shoelace sl-tab-group show() method\n * @see https://shoelace.style/components/tab-group?id=methods\n *\n * @param {Event} event\n * @param {string} event.params.showPanel - the name attribute of the sl-tab-panel to show\n * @example <button type='button' data-action=\"click->shoelace--tab-group#show\"\n * data-shoelace--tab-group-show-panel-param=\"mypanelname\">\n * @returns {void}\n */\n show(event) {\n const { showPanel } = event.params\n this.element.show(showPanel)\n }\n}\n","import { identifierForContextKey } from \"@hotwired/stimulus-webpack-helpers\"\n\nimport AddController from './refine/add-controller'\nimport CriterionFormController from './refine/criterion-form-controller'\nimport DefaultsController from './refine/defaults-controller'\nimport DeleteController from './refine/delete-controller'\nimport FilterPillsController from './refine/filter-pills-controller'\nimport PopupController from './refine/popup-controller'\nimport ModalController from './refine/modal-controller'\nimport SearchFilterController from './refine/search-filter-controller'\nimport ServerRefreshController from './refine/server-refresh-controller'\nimport StateController from './refine/state-controller'\nimport StoredFilterController from './refine/stored-filter-controller'\nimport SubmitForm from './refine/submit-form-controller'\nimport ToggleController from './refine/toggle-controller'\nimport TurboStreamFormController from './refine/turbo-stream-form-controller'\nimport TurboStreamLinkController from './refine/turbo-stream-link-controller'\nimport TypeaheadListController from './refine/typeahead-list-controller'\nimport UpdateController from './refine/update-controller'\nimport DateController from './refine/date-controller'\nimport InlineAdvancedModalController from \"./refine/inline-advanced-modal-controller\"\nimport TabGroupController from \"./fields/shoelace/tab-group-controller\"\n\nexport const controllerDefinitions = [\n [AddController, 'refine/add-controller.js'],\n [CriterionFormController, 'refine/criterion-form-controller.js'],\n [DefaultsController, 'refine/defaults-controller.js'],\n [DeleteController, 'refine/delete-controller.js'],\n [FilterPillsController, 'refine/filter-pills-controller.js'],\n [PopupController, 'refine/popup-controller.js'],\n [ModalController, 'refine/modal-controller.js'],\n [SearchFilterController, 'refine/search-filter-controller.js'],\n [ServerRefreshController, 'refine/server-refresh-controller.js'],\n [StateController, 'refine/state-controller.js'],\n [StoredFilterController, 'refine/stored-filter-controller.js'],\n [SubmitForm, 'refine/submit-form-controller.js'],\n [ToggleController, 'refine/toggle-controller.js'],\n [TurboStreamFormController, 'refine/turbo-stream-form-controller.js'],\n [TurboStreamLinkController, 'refine/turbo-stream-link-controller.js'],\n [TypeaheadListController, './refine/typeahead-list-controller.js'],\n [UpdateController, 'refine/update-controller.js'],\n [DateController, 'refine/date-controller.js'],\n [InlineAdvancedModalController, 'refine/inline-advanced-modal-controller.js'],\n [TabGroupController, 'fields/shoelace/tab-group-controller.js']\n].map(function(d) {\n const key = d[1]\n const controller = d[0]\n return {\n identifier: identifierForContextKey(key),\n controllerConstructor: controller\n }\n})\n\nexport {\n AddController,\n CriterionFormController,\n DefaultsController,\n DeleteController,\n FilterPillsController,\n PopupController,\n ModalController,\n SearchFilterController,\n ServerRefreshController,\n StateController,\n StoredFilterController,\n SubmitForm,\n ToggleController,\n TurboStreamFormController,\n TurboStreamLinkController,\n TypeaheadListController,\n UpdateController,\n DateController,\n InlineAdvancedModalController,\n TabGroupController\n}\n"],"names":["identifierForContextKey","key","logicalName","match","replace","Controller","connect","this","state","finishUpdate","currentElement","element","document","body","matches","application","getControllerForElementAndIdentifier","parentNode","refreshFromServer","options","_this","includeErrors","startUpdate","request","FetchRequest","refreshUrlValue","responseKind","query","filterName","JSON","stringify","blueprint","clientIdValue","include_errors","perform","then","e","Promise","reject","ServerRefreshController","criterion","resolve","validateBlueprint","isValid","addCriterion","previousCriterionIdValue","group","_this2","addGroup","_this3","validateBlueprintUrlValue","response","ok","values","previousCriterionId","Number","refresh","_event","formElement","getElementById","formIdValue","formData","FormData","urlValue","url","String","formId","getStateController","updateInput","criterionIdValue","inputValue","controller","criterionId","input","Object","deleteCriterion","urlParams","URLSearchParams","window","location","search","existingParams","delete","event","currentTarget","dataset","index","parseInt","stateController","reloadPage","submitUrlValue","refine_filters_builder","filter_class","blueprint_json","client_id","redirectToStableId","stableId","params","append","allParams","fromEntries","toString","pathname","history","pushState","title","reload","refineStateController","stabilizeFilterController","submitUrl","_class","useClickOutside","boundHandleKeyUp","handleKeyUp","bind","addEventListener","disconnect","removeEventListener","show","preventDefault","frameTarget","src","srcValue","isOpenValue","hide","stopPropagation","innerHTML","clickOutside","targets","isOpen","type","Boolean","default","open","close","submitFilter","activeElement","blur","querySelector","loadResults","_ref","detail","console","log","Turbo","visit","href","CustomEvent","bubbles","cancelable","undefined","evt","createEvent","initCustomEvent","prototype","Event","blueprintUpdatedEvent","_ref2","dispatchEvent","id","depth","condition","_clauses$","component","meta","clauses","refinements","selected","newInput","clause","forEach","refinement","condition_id","changeDelegate","delegate","blueprintValue","conditions","conditionsValue","classNameValue","conditionsLookup","reduce","lookup","loadingTimeout","abnegate","clearTimeout","setTimeout","loadingTarget","classList","remove","add","conditionConfigFor","conditionId","find","c","defaultConditionIdValue","length","push","word","splice","previous","next","previousIsOr","nextIsRightParen","previousIsLeftParen","isLastInGroup","replaceCriterion","criterionRow","Error","existingCriterion","newCriterion","isEqual","inputId","blueprintPath","split","Array","className","refreshUrl","clientId","validateBlueprintUrl","defaultConditionId","stateDomIdValue","blueprintFieldTarget","value","updateBlueprintField","stateDomId","submit","requestSubmit","toggle","contentTargets","node","toggleAttribute","TurboStreamFormController","method","action","turboMethod","filter","toLowerCase","handleFilter","clearSearch","visibleCategories","Set","listItemTargets","listItemNode","listItemValue","includes","hidden","category","recommendedTargets","recommendedNode","size","categoryTargets","categoryNode","has","initialize","updateBlueprint","debounce","inputKey","refinedFilter","target","select","slice","call","option","map","trim","newConditionId","config","cancelEnter","code","require","initPluginInstance","teardownPluginInstance","clearDate","$","fieldTarget","val","dispatch","applyDateToField","picker","format","includeTimeValue","timeFormatValue","dateFormatValue","momentVal","moment","startDate","toISOString","displayVal","dataVal","hiddenFieldTarget","trigger","localeValues","pickerLocaleValue","isAmPm","isAmPmValue","daterangepicker","singleDatePicker","timePicker","timePickerIncrement","autoUpdateInput","autoApply","minDate","futureOnlyValue","Date","locale","parentEl","drops","dropsValue","timePicker24Hour","on","showCalendar","pluginMainEl","plugin","data","inlineValue","off","includeTime","futureOnly","inline","dateFormat","timeFormat","datetimeFormat","pickerLocale","observer","IntersectionObserver","handleIntersection","root","scrollContainerTarget","threshold","rootMargin","bottomObserver","handleBottomIntersection","shouldHighlightCategories","handleHighlightTimeout","bottomMarker","categoryListItemTargets","item","observe","entries","entry","isIntersecting","intersectionRatio","highlightCategory","categoryListItemValue","categoryName","force","categoryShortcutItemTargets","inlineAdvancedModalValue","showSearchBar","searchBarInputTarget","hideSearchBar","findCategoryElementByName","clearSelection","debounceScrollHighlights","scrollToCategory","categoryElement","scrollIntoView","behavior","block","currentScrollYPosition","navigateToTab","handleTabShow","setLocationHash","keepScrollPositionValue","handleTabChange","hash","name","redirectedHashParam","get","newParams","replaceState","join","scrollY","showPanel","keepScrollPosition","controllerDefinitions","AddController","CriterionFormController","DefaultsController","DeleteController","FilterPillsController","PopupController","ModalController","SearchFilterController","StateController","StoredFilterController","SubmitForm","ToggleController","TurboStreamLinkController","TypeaheadListController","UpdateController","DateController","InlineAdvancedModalController","TabGroupController","d","identifier","controllerConstructor"],"mappings":"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"}
1
+ {"version":3,"file":"refine-stimulus.umd.js","sources":["../../../node_modules/@hotwired/stimulus-webpack-helpers/dist/stimulus-webpack-helpers.js","../../javascript/controllers/refine/server-refresh-controller.js","../../javascript/controllers/refine/add-controller.js","../../javascript/controllers/refine/criterion-form-controller.js","../../javascript/controllers/refine/defaults-controller.js","../../javascript/controllers/refine/delete-controller.js","../../javascript/controllers/refine/filter-pills-controller.js","../../javascript/controllers/refine/popup-controller.js","../../javascript/controllers/refine/modal-controller.js","../../javascript/controllers/refine/search-filter-controller.js","../../javascript/refine/helpers/index.js","../../javascript/controllers/refine/state-controller.js","../../javascript/controllers/refine/stored-filter-controller.js","../../javascript/controllers/refine/submit-form-controller.js","../../javascript/controllers/refine/toggle-controller.js","../../javascript/controllers/refine/turbo-stream-form-controller.js","../../javascript/controllers/refine/turbo-stream-link-controller.js","../../javascript/controllers/refine/typeahead-list-controller.js","../../javascript/controllers/refine/update-controller.js","../../javascript/controllers/refine/date-controller.js","../../javascript/controllers/refine/inline-advanced-modal-controller.js","../../javascript/controllers/fields/shoelace/tab-group-controller.js","../../javascript/controllers/index.js"],"sourcesContent":["/*\nStimulus Webpack Helpers 1.0.0\nCopyright © 2021 Basecamp, LLC\n */\nfunction definitionsFromContext(context) {\n return context.keys()\n .map((key) => definitionForModuleWithContextAndKey(context, key))\n .filter((value) => value);\n}\nfunction definitionForModuleWithContextAndKey(context, key) {\n const identifier = identifierForContextKey(key);\n if (identifier) {\n return definitionForModuleAndIdentifier(context(key), identifier);\n }\n}\nfunction definitionForModuleAndIdentifier(module, identifier) {\n const controllerConstructor = module.default;\n if (typeof controllerConstructor == \"function\") {\n return { identifier, controllerConstructor };\n }\n}\nfunction identifierForContextKey(key) {\n const logicalName = (key.match(/^(?:\\.\\/)?(.+)(?:[_-]controller\\..+?)$/) || [])[1];\n if (logicalName) {\n return logicalName.replace(/_/g, \"-\").replace(/\\//g, \"--\");\n }\n}\n\nexport { definitionForModuleAndIdentifier, definitionForModuleWithContextAndKey, definitionsFromContext, identifierForContextKey };\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n\n// Base class for controllers that reload form content from the server\nexport default class extends Controller {\n connect() {\n this.state.finishUpdate()\n }\n\n get state() {\n let currentElement = this.element\n\n while(currentElement !== document.body) {\n if (currentElement.matches('[data-controller~=\"refine--state\"]'))\n return this.application.getControllerForElementAndIdentifier(currentElement, 'refine--state')\n else {\n currentElement = currentElement.parentNode\n }\n }\n\n return null\n }\n\n async refreshFromServer(options = {}) {\n const { includeErrors } = options\n this.state.startUpdate()\n const request = new FetchRequest(\n \"GET\",\n this.state.refreshUrlValue,\n {\n responseKind: \"turbo-stream\",\n query: {\n \"refine_filters_builder[filter_class]\": this.state.filterName,\n \"refine_filters_builder[blueprint_json]\": JSON.stringify(this.state.blueprint),\n \"refine_filters_builder[client_id]\": this.state.clientIdValue,\n include_errors: !!includeErrors\n }\n }\n )\n await request.perform()\n }\n}\n","import ServerRefreshController from './server-refresh-controller'\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends ServerRefreshController {\n static values = {\n previousCriterionId: Number,\n }\n\n async criterion() {\n const isValid = await this.validateBlueprint()\n if (isValid) {\n this.state.addCriterion(this.previousCriterionIdValue)\n }\n this.refreshFromServer({includeErrors: !isValid})\n }\n\n async group() {\n const isValid = await this.validateBlueprint()\n if (isValid) {\n this.state.addGroup()\n }\n this.refreshFromServer({includeErrors: !isValid})\n }\n\n async validateBlueprint(blueprint) {\n const { state } = this\n\n const request = new FetchRequest(\n \"GET\",\n this.state.validateBlueprintUrlValue,\n {\n query: {\n \"refine_filters_builder[filter_class]\": this.state.filterName,\n \"refine_filters_builder[blueprint_json]\": JSON.stringify(this.state.blueprint),\n \"refine_filters_builder[client_id]\": this.state.clientIdValue\n }\n }\n )\n const response = await request.perform()\n return response.ok\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n This controller handles criteria forms\n (refine/inline/criteria/new|edit)\n*/\nexport default class extends Controller {\n static values = {\n url: String,\n formId: String\n }\n\n async refresh(_event) {\n // update the url with params from the form\n const formElement = document.getElementById(this.formIdValue)\n const formData = new FormData(formElement)\n\n const request = new FetchRequest(\n \"GET\",\n this.urlValue,\n {\n query: formData,\n responseKind: \"turbo-stream\"\n }\n )\n const response = await request.perform()\n }\n\n\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static values = {\n criterionId: Number,\n input: Object,\n };\n\n connect() {\n this.state = this.getStateController()\n\n this.state.updateInput(\n this.criterionIdValue,\n this.inputValue,\n );\n }\n\n getStateController() {\n let currentElement = this.element\n\n while(currentElement !== document.body) {\n const controller = this.application.getControllerForElementAndIdentifier(currentElement, 'refine--state')\n if (controller) {\n return controller\n } else {\n currentElement = currentElement.parentNode\n }\n }\n\n return null\n }\n}\n","import ServerRefreshController from './server-refresh-controller';\n\nexport default class extends ServerRefreshController {\n static values = {\n criterionId: Number,\n }\n\n criterion() {\n const { state, criterionIdValue } = this;\n state.deleteCriterion(criterionIdValue);\n this.refreshFromServer()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends Controller {\n static values = {\n submitUrl: String\n }\n\n connect() {\n const urlParams = new URLSearchParams(window.location.search)\n this.existingParams = urlParams\n this.existingParams.delete('stable_id')\n }\n\n delete(event) {\n const { criterionId } = event.currentTarget.dataset\n var index = parseInt(criterionId)\n this.stateController.deleteCriterion(index)\n this.reloadPage()\n }\n\n async reloadPage() {\n const {blueprint} = this.stateController\n const request = new FetchRequest(\n \"POST\",\n this.submitUrlValue,\n {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({\n refine_filters_builder: {\n filter_class: this.stateController.filterName,\n blueprint_json: JSON.stringify(blueprint),\n client_id: this.stateController.clientIdValue\n }\n })\n }\n )\n await request.perform()\n }\n\n redirectToStableId(stableId) {\n const params = new URLSearchParams()\n if (stableId) {\n params.append('stable_id', stableId)\n }\n const allParams = new URLSearchParams({\n ...Object.fromEntries(this.existingParams),\n ...Object.fromEntries(params),\n }).toString()\n const url = `${window.location.pathname}?${allParams}`\n\n history.pushState({}, document.title, url)\n window.location.reload()\n }\n\n get stateController() {\n return this.element.refineStateController\n }\n\n get stabilizeFilterController() {\n return this.element.stabilizeFilterController\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { useClickOutside } from 'stimulus-use'\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"frame\"]\n\n static values = {\n src: String,\n isOpen: {type: Boolean, default: false}\n }\n\n connect() {\n useClickOutside(this)\n this.boundHandleKeyUp = this.handleKeyUp.bind(this)\n document.addEventListener(\"keyup\", this.boundHandleKeyUp)\n }\n\n disconnect() {\n document.removeEventListener(\"keyup\", this.boundHandleKeyUp)\n }\n\n show(event) {\n event.preventDefault()\n this.frameTarget.src = this.srcValue;\n this.isOpenValue = true\n }\n\n hide(event) {\n if (this.isOpenValue) {\n event?.preventDefault()\n event?.stopPropagation()\n this.frameTarget.innerHTML = \"\";\n this.isOpenValue = false\n }\n }\n\n clickOutside(event) {\n this.hide(event)\n }\n\n handleKeyUp(event) {\n if (event.key === \"Escape\" || event.key === \"Esc\") {\n this.hide(event)\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { useClickOutside } from 'stimulus-use'\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"frame\"]\n\n static values = {\n src: String,\n isOpen: {type: Boolean, default: false}\n }\n\n connect() {\n useClickOutside(this)\n }\n\n disconnect() {\n }\n\n open(event) {\n event.preventDefault()\n this.frameTarget.src = this.srcValue;\n this.isOpenValue = true\n }\n\n close(event) {\n if (this.isOpenValue) {\n event?.preventDefault()\n this.frameTarget.innerHTML = \"\";\n this.isOpenValue = false\n }\n }\n\n clickOutside(event) {\n this.close(event)\n }\n\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\nexport default class extends Controller {\n static values = {\n submitUrl: String\n }\n\n\n search(event) {\n event.preventDefault()\n this.submitFilter()\n document.activeElement.blur()\n }\n\n async submitFilter() {\n console.log(\"Submitting filter: GEM\")\n const {blueprint} = this.stateController\n const request = new FetchRequest(\n \"POST\",\n this.submitUrlValue,\n {\n responseKind: \"turbo-stream\",\n body: JSON.stringify({\n refine_filters_builder: {\n filter_class: this.stateController.filterName,\n blueprint_json: JSON.stringify(blueprint),\n client_id: this.stateController.clientIdValue\n }\n })\n }\n )\n await request.perform()\n }\n\n get stateController() {\n return this\n .element\n .querySelector('[data-controller~=\"refine--state\"]')\n .refineStateController\n }\n\n loadResults({detail: {url}}) {\n console.log(\"filter submit success\")\n if (window.Turbo) {\n window.Turbo.visit(url)\n } else {\n window.location.href = url\n }\n }\n}\n","// Polyfill for custom events in IE9-11\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#polyfill\n;(function () {\n if (typeof window.CustomEvent === 'function') return false\n\n function CustomEvent(event, params) {\n params = params || { bubbles: false, cancelable: false, detail: undefined }\n var evt = document.createEvent('CustomEvent')\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n return evt\n }\n\n CustomEvent.prototype = window.Event.prototype\n\n window.CustomEvent = CustomEvent\n\n // eslint expects a return here\n return true\n})()\n\nexport const filterStabilizedEvent = (element, stableId, filterName) => {\n const event = new CustomEvent('filter-stabilized', {\n bubbles: true,\n cancelable: true,\n detail: {\n stableId,\n filterName,\n },\n })\n element.dispatchEvent(event)\n}\n\nexport const filterUnstableEvent = (blueprint) => {\n const event = new CustomEvent('filter-unstable', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const filterInvalidEvent = ({blueprint, errors}) => {\n const event = new CustomEvent('filter-invalid', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n errors,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const filterStoredEvent = (storedFilterId) => {\n const event = new CustomEvent('filter-stored', {\n bubbles: true,\n cancelable: true,\n detail: {\n storedFilterId,\n },\n })\n window.dispatchEvent(event)\n}\n\nexport const blueprintUpdatedEvent = (element, {blueprint, formId}) => {\n const event = new CustomEvent('blueprint-updated', {\n bubbles: true,\n cancelable: true,\n detail: {\n blueprint,\n formId\n },\n })\n element.dispatchEvent(event)\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { delegate, abnegate } from 'jquery-events-to-dom-events'\nimport { blueprintUpdatedEvent } from '../../refine/helpers'\nimport { isEqual } from 'lodash'\n\nconst criterion = (id, depth, condition) => {\n const component = condition?.component\n const meta = condition?.meta || { clauses: [], options: {}}\n const refinements = condition?.refinements || []\n const { clauses, options } = meta\n let selected\n if (component === 'option-condition') {\n selected = options[0] ? [options[0].id] : []\n } else {\n selected = undefined\n }\n // Set newInput based on component\n\n let newInput = {\n clause: clauses[0]?.id,\n selected: selected,\n }\n\n // If refinements are present, add to input array\n refinements.forEach((refinement) => {\n const { meta, component } = refinement\n const { clauses, options } = meta\n let selected\n if (component === 'option-condition') {\n selected = options[0] ? [options[0].id] : []\n } else {\n selected = undefined\n }\n newInput[refinement.id] = {\n clause: clauses[0].id,\n selected: selected,\n }\n })\n\n return {\n depth,\n type: 'criterion',\n condition_id: id,\n input: newInput,\n }\n}\n\nconst or = function (depth) {\n depth = depth === undefined ? 0 : depth\n return {\n depth,\n type: 'conjunction',\n word: 'or',\n }\n}\n\nconst and = function (depth) {\n depth = depth === undefined ? 1 : depth\n return {\n depth,\n type: 'conjunction',\n word: 'and',\n }\n}\nexport default class extends Controller {\n static values = {\n blueprint: Array,\n conditions: Array,\n className: String,\n refreshUrl: String,\n clientId: String,\n validateBlueprintUrl: String,\n defaultConditionId: String\n }\n static targets = ['loading']\n\n\n connect() {\n // for select2 jquery events and datepicker\n this.element.refineStateController = this\n this.changeDelegate = delegate('change', ['event', 'picker'])\n this.blueprint = this.blueprintValue\n this.conditions = this.conditionsValue\n this.filterName = this.classNameValue\n this.conditionsLookup = this.conditions.reduce((lookup, condition) => {\n lookup[condition.id] = condition\n return lookup\n }, {})\n this.loadingTimeout = null\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n disconnect() {\n abnegate('change', this.changeDelegate)\n }\n\n startUpdate() {\n if (this.loadingTimeout) {\n window.clearTimeout(this.loadingTimeout)\n }\n // only show the loading overlay if it's taking a long time\n // to render the updates\n this.loadingTimeout = window.setTimeout(() => {\n this.loadingTarget.classList.remove('hidden')\n }, 1000)\n }\n\n finishUpdate() {\n if (this.loadingTimeout) {\n window.clearTimeout(this.loadingTimeout)\n }\n this.loadingTarget.classList.add('hidden')\n }\n\n conditionConfigFor(conditionId) {\n return this.conditionsLookup[conditionId]\n }\n\n addGroup() {\n const { blueprint, conditions } = this\n const condition = ( conditions.find(c => c.id == this.defaultConditionIdValue) || conditions[0] )\n const { meta } = condition\n\n if (this.blueprint.length > 0) {\n this.blueprint.push(or())\n }\n this.blueprint.push(criterion(condition.id, 1, condition))\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n addCriterion(previousCriterionId) {\n const { blueprint, conditions } = this\n const condition = ( conditions.find(c => c.id == this.defaultConditionIdValue) || conditions[0] )\n const { meta } = condition\n blueprint.splice(previousCriterionId + 1, 0, and(), criterion(condition.id, 1, condition))\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n deleteCriterion(criterionId) {\n /**\n To support 'groups' there is some complicated logic for deleting criterion.\n\n Imagine this simplified blueprint: [eq, and, sw, or, eq]\n\n User clicks to delete the last eq. We also have to delete the preceding or\n otherwise we're left with a hanging empty group\n\n What if the user deletes the sw? We have to clean up the preceding and.\n\n Imagine another scenario: [eq or sw and ew]\n Now we delete the first eq but this time we need to clean up the or.\n\n These conditionals cover these cases.\n **/\n const { blueprint } = this\n const previous = blueprint[criterionId - 1]\n const next = blueprint[criterionId + 1]\n\n const nextIsOr = next && next.word === 'or'\n const previousIsOr = previous && previous.word === 'or'\n\n const nextIsRightParen = nextIsOr || !next\n const previousIsLeftParen = previousIsOr || !previous\n\n const isFirstInGroup = previousIsLeftParen && !nextIsRightParen\n const isLastInGroup = previousIsLeftParen && nextIsRightParen\n const isLastCriterion = !previous && !next\n\n if (isLastCriterion) {\n this.blueprint = []\n } else if (isLastInGroup && previousIsOr) {\n blueprint.splice(criterionId - 1, 2)\n } else if (isLastInGroup && !previous) {\n blueprint.splice(criterionId, 2)\n } else if (isFirstInGroup) {\n blueprint.splice(criterionId, 2)\n } else {\n blueprint.splice(criterionId - 1, 2)\n }\n\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n /*\n Updates a criterion in the blueprint\n Returns true if an update was actually performed, or false if no-op\n */\n replaceCriterion(criterionId, conditionId, condition) {\n const criterionRow = this.blueprint[criterionId]\n if (criterionRow.type !== 'criterion') {\n throw new Error(\n `You can't call updateConditionId on a non-criterion type. Trying to update ${JSON.stringify(criterion)}`\n )\n }\n const existingCriterion = this.blueprint[criterionId]\n const newCriterion = criterion(conditionId, criterionRow.depth, condition)\n if (isEqual(existingCriterion, newCriterion)) {\n return false\n } else {\n this.blueprint[criterionId] = newCriterion\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n return true\n }\n }\n\n updateInput(criterionId, input, inputId) {\n // Input id is an array of hash keys that define the path for this input such as [\"input\", \"date_refinement\"]\n const { blueprint } = this\n const criterion = blueprint[criterionId]\n inputId = inputId || 'input'\n const blueprintPath = inputId.split(', ')\n // If the inputId contains more than one element, add input at appropriate depth\n if (blueprintPath.length > 1) {\n criterion[blueprintPath[0]][blueprintPath[1]] = { ...criterion[blueprintPath[0]][blueprintPath[1]], ...input }\n } else {\n criterion[inputId] = { ...criterion[inputId], ...input }\n }\n blueprintUpdatedEvent(this.element, {blueprint: this.blueprint, formId: this.formIdValue})\n }\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { filterStoredEvent } from '../../refine/helpers'\n\nexport default class extends Controller {\n static targets = ['blueprintField']\n static values = { formId: String, stateDomId: String }\n\n connect() {\n const stateController = document\n .getElementById(this.stateDomIdValue)\n .refineStateController\n this.blueprintFieldTarget.value = JSON.stringify(stateController.blueprint)\n console.log(\"connect\", this.blueprintFieldTarget.value)\n }\n\n updateBlueprintField(event) {\n if (event.detail.formId != this.formIdValue) { return null }\n const { detail } = event\n const { blueprint } = detail\n this.blueprintFieldTarget.value = JSON.stringify(blueprint)\n console.log(\"update blueprint\", this.blueprintFieldTarget.value)\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n submit(event) {\n event.preventDefault()\n this.element.requestSubmit()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\n// simple controller to hide/show the filter modal\nexport default class extends Controller {\n static targets = [\"content\"]\n\n toggle(_event) {\n this.contentTargets.forEach(node => {\n node.toggleAttribute(\"hidden\")\n })\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n attach to a form element to have it submit to a turbo-stream endpoint\n\n <form action=\"/contacts\" data-controller=\"refine--turbo-stream-form\" data-action=\"submit->refine--turbo-stream-form#submit\">\n\n Turbo is supposed to handle this natively but we're seeing issues when the form is inside an iframe\n*/\nexport default class extends Controller {\n async submit(event) {\n event.preventDefault()\n const request = new FetchRequest(\n (this.element.method || \"POST\"),\n this.element.action,\n {\n responseKind: \"turbo-stream\",\n body: new FormData(this.element)\n }\n )\n await request.perform()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport { FetchRequest } from '@rails/request.js'\n\n/*\n attach to a link element to have it request turbo stream responses\n\n <a href=\"/contacts\" data-controller=\"refine--turbo-stream-link\" data-action=\"refine--turbo-stream-link#get\">Click me</a>\n\n Turbo is supposed to handle this natively with data-turbo-stream but we're\n seeing issues using that attribute inside iframes\n*/\nexport default class extends Controller {\n async visit(event) {\n event.preventDefault()\n const request = new FetchRequest(\n (this.element.dataset.turboMethod || \"GET\"),\n this.element.href,\n {\n responseKind: \"turbo-stream\",\n }\n )\n await request.perform()\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n\n static targets = ['listItem', 'category', 'recommended']\n\n filter(event) {\n const query = event.currentTarget.value.toLowerCase()\n this.handleFilter(query) \n }\n\n clearSearch() {\n this.handleFilter('')\n }\n\n handleFilter(query) {\n const visibleCategories = new Set()\n\n // hide / show listItem links that match the query and note which\n // categories should be visible\n this.listItemTargets.forEach(listItemNode => {\n const listItemName = listItemNode.dataset.listItemValue.toLowerCase()\n if (listItemName.includes(query)) {\n listItemNode.hidden = false\n visibleCategories.add(listItemNode.dataset.category)\n } else {\n listItemNode.hidden = true\n }\n })\n\n this.recommendedTargets.forEach(recommendedNode => {\n (query !== '' && visibleCategories.size === 0) ? recommendedNode.hidden = true : recommendedNode.hidden = false\n })\n\n // hide / show category headers that have visible listItems\n this.categoryTargets.forEach(categoryNode => {\n const categoryName = categoryNode.innerHTML\n if (visibleCategories.has(categoryName)) {\n categoryNode.hidden = false\n } else {\n categoryNode.hidden = true\n }\n })\n }\n}\n","import ServerRefreshController from './server-refresh-controller'\nimport { debounce } from 'lodash'\n\nexport default class extends ServerRefreshController {\n static values = {\n criterionId: Number,\n }\n\n initialize() {\n this.updateBlueprint = debounce((event, value, inputKey) => {\n this.value(event, value, inputKey)\n }, 500)\n }\n\n refinedFilter(event) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n\n state.updateInput(\n criterionIdValue,\n {\n id: event.target.value,\n },\n inputId\n )\n this.refreshFromServer()\n }\n\n clause(event) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n state.updateInput(\n criterionIdValue,\n {\n clause: event.target.value,\n },\n inputId\n )\n this.refreshFromServer()\n }\n\n selected(event) {\n const { target: select } = event\n const options = Array.prototype.slice.call(select.options)\n const selectedOptions = options.filter((option) => option.selected)\n const selected = selectedOptions.map((option) => option.value)\n this.value(event, selected, 'selected')\n }\n\n value(event, value, inputKey) {\n const { criterionIdValue, state } = this\n const dataset = event.target.dataset\n const inputId = dataset.inputId\n inputKey = inputKey || dataset.inputKey || 'value'\n value = value || event.target.value\n if(typeof value === 'string')\n value = value.trim()\n state.updateInput(\n criterionIdValue,\n {\n [inputKey]: value,\n },\n inputId\n )\n }\n\n condition(event) {\n const { criterionIdValue, state } = this\n const element = event.target\n let newConditionId = element.value\n if (!newConditionId) newConditionId = element.querySelector('select').value \n const config = this.state.conditionConfigFor(newConditionId)\n const updatePerformed = state.replaceCriterion(criterionIdValue, newConditionId, config)\n if (updatePerformed) {\n this.refreshFromServer()\n }\n }\n\n // Prevent form submission when hitting enter in a text box\n cancelEnter(event) {\n if (event.code === \"Enter\") {\n event.preventDefault()\n event.stopPropagation()\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\nimport moment from 'moment'\nrequire('daterangepicker/daterangepicker.css')\n\n// requires jQuery, moment, might want to consider a vanilla JS alternative\nimport $ from 'jquery' // ensure jquery is loaded before daterangepicker\nimport 'daterangepicker'\n\nexport default class extends Controller {\n static targets = [\n 'field',\n 'hiddenField',\n 'clearButton',\n ]\n\n static values = {\n includeTime: Boolean,\n futureOnly: Boolean,\n drops: String,\n inline: Boolean,\n dateFormat: String,\n timeFormat: String,\n isAmPm: Boolean,\n locale: { type: String, default: 'en' },\n datetimeFormat: { type: String, default: 'MM/DD/YYYY h:mm A' },\n pickerLocale: { type: Object, default: {} },\n }\n\n connect() {\n this.initPluginInstance()\n }\n\n disconnect() {\n this.teardownPluginInstance()\n }\n\n clearDate(event) {\n // don't submit the form, unless it originated from the cancel/clear button\n event.preventDefault()\n\n window.$(this.fieldTarget).val('')\n\n this.dispatch('value-cleared')\n }\n\n applyDateToField(event, picker) {\n const format = this.includeTimeValue ? this.timeFormatValue : this.dateFormatValue\n\n const momentVal = picker\n ? moment(picker.startDate.toISOString())\n : moment(this.fieldTarget.value, 'YYYY-MM-DDTHH:mm').format('YYYY-MM-DDTHH:mm')\n const displayVal = momentVal.format(format)\n const dataVal = this.includeTimeValue ? momentVal.toISOString(true) : momentVal.format('YYYY-MM-DD')\n\n this.fieldTarget.value = displayVal\n this.hiddenFieldTarget.value = dataVal\n // bubble up a change event when the input is updated for other listeners\n window.$(this.fieldTarget).trigger('change', picker)\n\n // emit native change event\n this.hiddenFieldTarget.dispatchEvent(new Event('change', { detail: picker, bubbles: true }))\n }\n\n initPluginInstance() {\n const localeValues = this.pickerLocaleValue\n const isAmPm = this.isAmPmValue\n localeValues['format'] = this.includeTimeValue ? this.timeFormatValue : this.dateFormatValue\n\n window.$(this.fieldTarget).daterangepicker({\n singleDatePicker: true,\n timePicker: this.includeTimeValue,\n timePickerIncrement: 5,\n autoUpdateInput: false,\n autoApply: true,\n minDate: this.futureOnlyValue ? new Date() : false,\n locale: localeValues,\n parentEl: $(this.element),\n drops: this.dropsValue ? this.dropsValue : 'down',\n timePicker24Hour: !isAmPm,\n })\n\n window.$(this.fieldTarget).on('apply.daterangepicker', this.applyDateToField.bind(this))\n window.$(this.fieldTarget).on('cancel.daterangepicker', this.clearDate.bind(this))\n window.$(this.fieldTarget).on('showCalendar.daterangepicker', this.showCalendar.bind(this))\n\n this.pluginMainEl = this.fieldTarget\n this.plugin = $(this.pluginMainEl).data('daterangepicker') // weird\n\n if (this.inlineValue) {\n this.element.classList.add('date-input--inline')\n }\n\n }\n \n teardownPluginInstance() {\n if (this.plugin === undefined) {\n return\n }\n\n $(this.pluginMainEl).off('apply.daterangepicker')\n $(this.pluginMainEl).off('cancel.daterangepicker')\n $(this.pluginMainEl).off('showCalendar.daterangepicker')\n\n // revert to original markup, remove any event listeners\n this.plugin.remove()\n\n }\n\n showCalendar() {\n this.dispatch('show-calendar')\n }\n\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n\n static targets = ['searchBarInput', 'categoryListItem', 'categoryBlockItem', 'categoryShortcutItem', 'scrollContainer']\n\n connect() {\n this.observer = new IntersectionObserver(\n this.handleIntersection.bind(this), {\n root: this.scrollContainerTarget,\n threshold: 1.0,\n rootMargin: '0px 0px -80% 0px'\n }\n )\n\n this.bottomObserver = new IntersectionObserver(\n this.handleBottomIntersection.bind(this), {\n root: this.scrollContainerTarget,\n threshold: 1.0\n }\n )\n\n this.shouldHighlightCategories = true;\n this.handleHighlightTimeout = null;\n this.bottomMarker = document.getElementById('refine--picker-bottom-marker');\n\n this.categoryListItemTargets.forEach(item => this.observer.observe(item))\n this.bottomObserver.observe(this.bottomMarker)\n }\n\n disconnect() {\n this.bottomObserver.disconnect()\n this.observer.disconnect()\n }\n\n handleIntersection(entries) {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target !== this.bottomMarker) {\n if(entry.intersectionRatio == 1) {\n this.highlightCategory(entry.target.dataset.categoryListItemValue)\n }\n }\n })\n }\n\n handleBottomIntersection(entries) {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target === this.bottomMarker) {\n this.highlightCategory(this.categoryListItemTargets[this.categoryListItemTargets.length - 1].dataset.categoryListItemValue)\n }\n })\n }\n \n\n highlightCategory(categoryName, force=false) {\n if(this.shouldHighlightCategories || force) {\n this.categoryShortcutItemTargets.forEach(item => {\n if(item.dataset.inlineAdvancedModalValue === categoryName) {\n item.classList.add('active')\n } else {\n item.classList.remove('active')\n }\n })\n }\n }\n\n showSearchBar() {\n this.searchBarInputTarget.hidden = false\n }\n\n hideSearchBar() {\n this.searchBarInputTarget.hidden = true\n }\n\n findCategoryElementByName(categoryName) {\n // Use the find method to locate the target with the specified attribute value\n return this.categoryListItemTargets.find(item => item.dataset.categoryListItemValue === categoryName)\n }\n\n clearSelection() {\n this.debounceScrollHighlights();\n this.categoryShortcutItemTargets.forEach((item) => {\n item.classList.remove('active')\n })\n }\n\n clearSearch() {\n if (this.searchBarInputTarget.querySelector(\"input\")) {\n this.searchBarInputTarget.querySelector(\"input\").value = ''\n }\n }\n\n scrollToCategory(event) {\n const categoryName = event.target.dataset.inlineAdvancedModalValue\n const categoryElement = this.findCategoryElementByName(categoryName)\n if(categoryElement) {\n this.shouldHighlightCategories = false;\n categoryElement.scrollIntoView({\n behavior: \"smooth\",\n block: \"start\",\n inline: \"nearest\"\n })\n setTimeout(() => {\n this.shouldHighlightCategories = true;\n this.highlightCategory(categoryName, true);\n }, 750);\n }\n }\n\n debounceScrollHighlights() {\n this.shouldHighlightCategories = false;\n clearTimeout(this.handleHighlightTimeout);\n this.handleHighlightTimeout = setTimeout(() => {\n this.shouldHighlightCategories = true;\n }, 1000)\n }\n \n}\n","// to be used with sl-tab-group\nimport { Controller } from \"@hotwired/stimulus\"\n\n// This controller is used to handle the tab group component\n// @see https://shoelace.style/components/tab-group\n// @param keepScrollPosition [Boolean] - If true, the scroll position will be kept when changing tabs\n// @usage <div data-controller=\"shoelace--tab-group\" data-shoelace--tab-group-keep-scroll-position-value=\"true\">\n\nexport default class extends Controller {\n static values = {\n keepScrollPosition: { type: Boolean, default: false },\n }\n\n connect() {\n this.currentScrollYPosition = 0\n this.navigateToTab = this.navigateToTab.bind(this)\n this.handleTabShow = this.handleTabShow.bind(this)\n\n this.navigateToTab()\n\n document.addEventListener('turbo:load', this.navigateToTab)\n this.element.addEventListener('sl-tab-show', this.handleTabShow)\n }\n\n disconnect() {\n document.removeEventListener('turbo:load', this.navigateToTab)\n this.element.removeEventListener('sl-tab-show', this.handleTabShow)\n }\n\n handleTabShow(event) {\n this.setLocationHash(event)\n\n if (this.keepScrollPositionValue) {\n this.handleTabChange()\n }\n }\n\n setLocationHash(event) {\n window.location.hash = event.detail.name\n }\n\n navigateToTab() {\n let hash = window.location.hash.toString()\n if (hash) {\n this.element.show(hash.slice(1))\n } else {\n /*\n * Turbo doesn't currently support hashes on redirects (see https://github.com/hotwired/turbo/issues/825)\n * so we've created a workaround. Pass `redirect_anchor` as a query param, and the component will convert\n * it to a hash and delete the query param. e.g. `some_url?redirect_anchor=store_upsells`\n */\n const params = new URLSearchParams(window.location.search)\n const redirectedHashParam = params.get('redirect_anchor')\n if (redirectedHashParam) {\n params.delete('redirect_anchor')\n let newParams = params.toString()\n window.history.replaceState(\n null,\n '',\n [window.location.pathname, newParams ? `?${newParams}` : '', '#', redirectedHashParam].join('')\n )\n }\n }\n }\n\n handleTabChange() {\n this.currentScrollYPosition = window.scrollY\n }\n\n /**\n * Programmatically reveal a sl-tab-panel via action params.\n * @see Shoelace sl-tab-group show() method\n * @see https://shoelace.style/components/tab-group?id=methods\n *\n * @param {Event} event\n * @param {string} event.params.showPanel - the name attribute of the sl-tab-panel to show\n * @example <button type='button' data-action=\"click->shoelace--tab-group#show\"\n * data-shoelace--tab-group-show-panel-param=\"mypanelname\">\n * @returns {void}\n */\n show(event) {\n const { showPanel } = event.params\n this.element.show(showPanel)\n }\n}\n","import { identifierForContextKey } from \"@hotwired/stimulus-webpack-helpers\"\n\nimport AddController from './refine/add-controller'\nimport CriterionFormController from './refine/criterion-form-controller'\nimport DefaultsController from './refine/defaults-controller'\nimport DeleteController from './refine/delete-controller'\nimport FilterPillsController from './refine/filter-pills-controller'\nimport PopupController from './refine/popup-controller'\nimport ModalController from './refine/modal-controller'\nimport SearchFilterController from './refine/search-filter-controller'\nimport ServerRefreshController from './refine/server-refresh-controller'\nimport StateController from './refine/state-controller'\nimport StoredFilterController from './refine/stored-filter-controller'\nimport SubmitForm from './refine/submit-form-controller'\nimport ToggleController from './refine/toggle-controller'\nimport TurboStreamFormController from './refine/turbo-stream-form-controller'\nimport TurboStreamLinkController from './refine/turbo-stream-link-controller'\nimport TypeaheadListController from './refine/typeahead-list-controller'\nimport UpdateController from './refine/update-controller'\nimport DateController from './refine/date-controller'\nimport InlineAdvancedModalController from \"./refine/inline-advanced-modal-controller\"\nimport TabGroupController from \"./fields/shoelace/tab-group-controller\"\n\nexport const controllerDefinitions = [\n [AddController, 'refine/add-controller.js'],\n [CriterionFormController, 'refine/criterion-form-controller.js'],\n [DefaultsController, 'refine/defaults-controller.js'],\n [DeleteController, 'refine/delete-controller.js'],\n [FilterPillsController, 'refine/filter-pills-controller.js'],\n [PopupController, 'refine/popup-controller.js'],\n [ModalController, 'refine/modal-controller.js'],\n [SearchFilterController, 'refine/search-filter-controller.js'],\n [ServerRefreshController, 'refine/server-refresh-controller.js'],\n [StateController, 'refine/state-controller.js'],\n [StoredFilterController, 'refine/stored-filter-controller.js'],\n [SubmitForm, 'refine/submit-form-controller.js'],\n [ToggleController, 'refine/toggle-controller.js'],\n [TurboStreamFormController, 'refine/turbo-stream-form-controller.js'],\n [TurboStreamLinkController, 'refine/turbo-stream-link-controller.js'],\n [TypeaheadListController, './refine/typeahead-list-controller.js'],\n [UpdateController, 'refine/update-controller.js'],\n [DateController, 'refine/date-controller.js'],\n [InlineAdvancedModalController, 'refine/inline-advanced-modal-controller.js'],\n [TabGroupController, 'fields/shoelace/tab-group-controller.js']\n].map(function(d) {\n const key = d[1]\n const controller = d[0]\n return {\n identifier: identifierForContextKey(key),\n controllerConstructor: controller\n }\n})\n\nexport {\n AddController,\n CriterionFormController,\n DefaultsController,\n DeleteController,\n FilterPillsController,\n PopupController,\n ModalController,\n SearchFilterController,\n ServerRefreshController,\n StateController,\n StoredFilterController,\n SubmitForm,\n ToggleController,\n TurboStreamFormController,\n TurboStreamLinkController,\n TypeaheadListController,\n UpdateController,\n DateController,\n InlineAdvancedModalController,\n TabGroupController\n}\n"],"names":["identifierForContextKey","key","logicalName","match","replace","Controller","connect","this","state","finishUpdate","currentElement","element","document","body","matches","application","getControllerForElementAndIdentifier","parentNode","refreshFromServer","options","_this","includeErrors","startUpdate","request","FetchRequest","refreshUrlValue","responseKind","query","filterName","JSON","stringify","blueprint","clientIdValue","include_errors","perform","then","e","Promise","reject","ServerRefreshController","criterion","resolve","validateBlueprint","isValid","addCriterion","previousCriterionIdValue","group","_this2","addGroup","_this3","validateBlueprintUrlValue","response","ok","values","previousCriterionId","Number","refresh","_event","formElement","getElementById","formIdValue","formData","FormData","urlValue","url","String","formId","getStateController","updateInput","criterionIdValue","inputValue","controller","criterionId","input","Object","deleteCriterion","urlParams","URLSearchParams","window","location","search","existingParams","delete","event","currentTarget","dataset","index","parseInt","stateController","reloadPage","submitUrlValue","refine_filters_builder","filter_class","blueprint_json","client_id","redirectToStableId","stableId","params","append","allParams","fromEntries","toString","pathname","history","pushState","title","reload","refineStateController","stabilizeFilterController","submitUrl","_class","useClickOutside","boundHandleKeyUp","handleKeyUp","bind","addEventListener","disconnect","removeEventListener","show","preventDefault","frameTarget","src","srcValue","isOpenValue","hide","stopPropagation","innerHTML","clickOutside","targets","isOpen","type","Boolean","default","open","close","submitFilter","activeElement","blur","console","log","querySelector","loadResults","_ref","detail","Turbo","visit","href","CustomEvent","bubbles","cancelable","undefined","evt","createEvent","initCustomEvent","prototype","Event","blueprintUpdatedEvent","_ref2","dispatchEvent","id","depth","condition","_clauses$","component","meta","clauses","refinements","selected","newInput","clause","forEach","refinement","condition_id","changeDelegate","delegate","blueprintValue","conditions","conditionsValue","classNameValue","conditionsLookup","reduce","lookup","loadingTimeout","abnegate","clearTimeout","setTimeout","loadingTarget","classList","remove","add","conditionConfigFor","conditionId","find","c","defaultConditionIdValue","length","push","word","splice","previous","next","previousIsOr","nextIsRightParen","previousIsLeftParen","isLastInGroup","replaceCriterion","criterionRow","Error","existingCriterion","newCriterion","isEqual","inputId","blueprintPath","split","Array","className","refreshUrl","clientId","validateBlueprintUrl","defaultConditionId","stateDomIdValue","blueprintFieldTarget","value","updateBlueprintField","stateDomId","submit","requestSubmit","toggle","contentTargets","node","toggleAttribute","TurboStreamFormController","method","action","turboMethod","filter","toLowerCase","handleFilter","clearSearch","visibleCategories","Set","listItemTargets","listItemNode","listItemValue","includes","hidden","category","recommendedTargets","recommendedNode","size","categoryTargets","categoryNode","has","initialize","updateBlueprint","debounce","inputKey","refinedFilter","target","select","slice","call","option","map","trim","newConditionId","config","cancelEnter","code","require","initPluginInstance","teardownPluginInstance","clearDate","$","fieldTarget","val","dispatch","applyDateToField","picker","format","includeTimeValue","timeFormatValue","dateFormatValue","momentVal","moment","startDate","toISOString","displayVal","dataVal","hiddenFieldTarget","trigger","localeValues","pickerLocaleValue","isAmPm","isAmPmValue","daterangepicker","singleDatePicker","timePicker","timePickerIncrement","autoUpdateInput","autoApply","minDate","futureOnlyValue","Date","locale","parentEl","drops","dropsValue","timePicker24Hour","on","showCalendar","pluginMainEl","plugin","data","inlineValue","off","includeTime","futureOnly","inline","dateFormat","timeFormat","datetimeFormat","pickerLocale","observer","IntersectionObserver","handleIntersection","root","scrollContainerTarget","threshold","rootMargin","bottomObserver","handleBottomIntersection","shouldHighlightCategories","handleHighlightTimeout","bottomMarker","categoryListItemTargets","item","observe","entries","entry","isIntersecting","intersectionRatio","highlightCategory","categoryListItemValue","categoryName","force","categoryShortcutItemTargets","inlineAdvancedModalValue","showSearchBar","searchBarInputTarget","hideSearchBar","findCategoryElementByName","clearSelection","debounceScrollHighlights","scrollToCategory","categoryElement","scrollIntoView","behavior","block","currentScrollYPosition","navigateToTab","handleTabShow","setLocationHash","keepScrollPositionValue","handleTabChange","hash","name","redirectedHashParam","get","newParams","replaceState","join","scrollY","showPanel","keepScrollPosition","controllerDefinitions","AddController","CriterionFormController","DefaultsController","DeleteController","FilterPillsController","PopupController","ModalController","SearchFilterController","StateController","StoredFilterController","SubmitForm","ToggleController","TurboStreamLinkController","TypeaheadListController","UpdateController","DateController","InlineAdvancedModalController","TabGroupController","d","identifier","controllerConstructor"],"mappings":"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"}
@@ -29,14 +29,12 @@ module Refine::Conditions
29
29
  # TODO Determine right place to set the clause
30
30
  validate_user_input(input)
31
31
  if input.dig(:filter_refinement).present?
32
- # TODO - Handle refinements. Currently not working for flat queries because its dependent on the pending_subquery system
33
32
 
34
33
  filter_condition = call_proc_if_callable(@filter_refinement_proc)
35
34
  # Set the filter on the filter_condition to be the current_condition's filter
36
35
  filter_condition.set_filter(filter)
37
36
  filter_condition.is_refinement = true
38
37
 
39
- # Applying the filter condition will modify pending relationship subqueries in place
40
38
  filter_condition.apply(input.dig(:filter_refinement), table, initial_query)
41
39
  input.delete(:filter_refinement)
42
40
  end
@@ -55,59 +53,80 @@ module Refine::Conditions
55
53
  end
56
54
 
57
55
  def handle_flat_relational_condition(input:, table:, query:, inverse_clause:)
58
- # Split on first .
59
- decompose_attribute = @attribute.split(".", 2)
60
- # Attribute now is the back half of the initial attribute
61
- @attribute = decompose_attribute[1]
62
- # Relation to be handled
63
- relation = decompose_attribute[0]
64
-
65
-
66
- # Get the Reflection object which defines the relationship between query and relation
67
- # First iteration pull relationship using base query which responds to model.
68
- instance = if query.respond_to? :model
69
- query.model.reflect_on_association(relation.to_sym)
70
- else
71
- # When query is sent in as subquery (recursive) the query object is the model class pulled from the
72
- # previous instance value
73
- query.reflect_on_association(relation.to_sym)
74
- end
75
-
76
- through_reflection = instance
77
- forced_id = false
78
-
79
- # TODO - make sure we're accounting for refinements
80
- if @attribute == "id"
81
- # We're referencing a primary key ID, so we dont need the final join table and
82
- # can just reference the foreign key of the previous step in the relation chain
83
- through_reflection = get_through_reflection(instance: instance, relation: decompose_attribute[0])
84
- unless condition_uses_different_database?(through_reflection.klass, query.model)
85
- forced_id = true
86
- @attribute = get_foreign_key_from_relation(instance: instance, reflection: through_reflection)
56
+ model_class = query.model
57
+ condition_joins = []
58
+ while @attribute.include?(".")
59
+ forced_id = false
60
+ # Split on first .
61
+ decompose_attribute = @attribute.split(".", 2)
62
+ # Attribute now is the back half of the initial attribute
63
+ @attribute = decompose_attribute[1]
64
+ # Relation to be handled
65
+ relation = decompose_attribute[0]
66
+
67
+ instance = model_class.reflect_on_association(relation.to_sym)
68
+
69
+ if @attribute == "id"
70
+ # We're referencing a primary key ID, so we dont need the final join table and
71
+ # can just reference the foreign key of the previous step in the relation chain
72
+ model_class = instance.class_name.safe_constantize
73
+ through_reflection = get_through_reflection(instance: instance, relation: relation)
74
+ unless condition_uses_different_database?(through_reflection.klass, query.model)
75
+ forced_id = true
76
+ @attribute = get_foreign_key_from_relation(instance: instance, reflection: through_reflection)
77
+ unless condition_uses_different_database?(model_class, query.model)
78
+ condition_joins << through_reflection.name
79
+ end
80
+ end
81
+ else
82
+ # Track the loop iteration of needing joins.
83
+ # The resulting array will be used to construct a nested joins statement
84
+ # IE: [forms_submissions, forms_submissions_answers] will later be converted to forms_submissions: {forms_submissions_answers: {}}
85
+ unless condition_uses_different_database?(model_class, query.model)
86
+ condition_joins << relation
87
+ end
87
88
  end
88
- end
89
+ model_class = instance.class_name.safe_constantize
90
+
91
+ end # End of while loop
89
92
 
90
- unless condition_uses_different_database?(through_reflection.klass, query.model)
91
- add_pending_joins_if_needed(instance: instance, reflection: through_reflection, input: input)
93
+ if condition_joins.any?
94
+ add_pending_joins_if_needed(input: input, joins_array: condition_joins)
92
95
  end
93
- # TODO - this is not the right long-term place for this.
94
- apply_flat_relational_condition(instance: instance, relation: relation, through_reflection: through_reflection, input: input, table: table, query: query, inverse_clause: inverse_clause, forced_id: forced_id)
96
+
97
+ apply_flat_relational_condition(instance: instance, relation: relation, through_reflection: through_reflection, input: input, query: query, inverse_clause: inverse_clause, forced_id: forced_id)
95
98
  end
96
99
 
97
- def apply_flat_relational_condition(instance:, relation:, through_reflection:, input:, table:, query:, inverse_clause:, forced_id: false)
100
+ # apply_flat_relational_condition
101
+ # instance: The reflection object for the relationship
102
+ # relation: The name of the relationship
103
+ # through_reflection: The reflection object for the through relationship if applicable. Might be nil
104
+ # input: The user input for the condition
105
+ # query: The base query the condition is being applied to
106
+ # inverse_clause: Whether to invert the clause
107
+ # forced_id: Whether to force the ID of the instance to be used. This is used when the condition is referencing a primary key
108
+ def apply_flat_relational_condition(instance:, relation:, through_reflection:, input:, query:, inverse_clause:, forced_id: false)
98
109
  unless instance
99
110
  raise "Relationship does not exist for #{relation}."
100
111
  end
101
112
 
102
- relation_table_being_queried = through_reflection.klass.arel_table
103
- relation_class = through_reflection.klass
113
+ if through_reflection
114
+ # If through reflection is passed in (due to an association only referencing the id)
115
+ # use that to get the table and class
116
+ relation_table_being_queried = through_reflection.klass.arel_table
117
+ relation_class = through_reflection.klass
118
+ else
119
+ # Otherwise, use the instance to get the table and class.
120
+ relation_table_being_queried = instance.class_name.safe_constantize&.arel_table
121
+ relation_class = instance.class_name.safe_constantize
122
+ end
104
123
 
105
124
  instance = get_reflection_object(query, relation) if forced_id
106
125
 
107
126
  key_1 = key_1(instance)
108
127
  key_2 = key_2(instance)
109
128
  if condition_uses_different_database?(relation_class, query.model)
110
- nodes = handle_flat_cross_database_condition(input: input, table: table, relation_class: relation_class, relation_table_being_queried: relation_table_being_queried, inverse_clause: inverse_clause, key_1: key_1, key_2: key_2)
129
+ nodes = handle_flat_cross_database_condition(root_model: query.model, input: input, relation_class: relation_class, relation_table_being_queried: relation_table_being_queried, inverse_clause: inverse_clause, key_1: key_1, key_2: key_2)
111
130
  else
112
131
  if forced_id
113
132
  nodes = apply(input, relation_table_being_queried, query, inverse_clause, key_2)
@@ -126,7 +145,8 @@ module Refine::Conditions
126
145
 
127
146
  # When we need to go to another DB for the relation. We need to do a separate query to get the IDS of
128
147
  # the records matching the condition that will then be passed into the primary query.
129
- def handle_flat_cross_database_condition(input:, table:, relation_class:, relation_table_being_queried:, inverse_clause:, key_1:, key_2:)
148
+ def handle_flat_cross_database_condition(root_model:, input:, relation_class:, relation_table_being_queried:, inverse_clause:, key_1:, key_2:)
149
+ table = root_model.arel_table
130
150
  relational_query = relation_class.select(key_2).arel
131
151
  node = apply(input, relation_table_being_queried, relation_class, inverse_clause)
132
152
  relational_query = relational_query.where(node)
@@ -156,21 +176,22 @@ module Refine::Conditions
156
176
  child_foreign_key
157
177
  end
158
178
 
159
- def add_pending_join(relation, join_type=:inner)
179
+ def add_pending_join(joins_array, join_type=:inner)
180
+ relation = joins_array.first
181
+ joins_block = joins_array.reverse.inject({}) { |a, n| { n.to_sym => a } }
160
182
  # If we already are tracking the relation with a left joins, don't overwrite it
161
- # puts "adding a pending join for relation: #{relation} with join type: #{join_type}"
162
- unless join_type == :inner && filter.pending_joins[relation] == :left
183
+ unless join_type == :inner && filter.pending_joins[relation] && filter.pending_joins[relation][:type] == :left
163
184
  filter.needs_distinct = true
164
- filter.pending_joins[relation] = join_type
185
+ filter.pending_joins[relation] = { type: join_type, joins_block: joins_block}.compact
165
186
  end
166
187
  end
167
188
 
168
- def add_pending_joins_if_needed(instance:, reflection:, input:)
189
+ def add_pending_joins_if_needed(input:, joins_array:)
169
190
  # Determine if we need to do left-joins due to the clause needing to include null values
170
191
  if(input && LEFT_JOIN_CLAUSES.include?(input[:clause]))
171
- add_pending_join(reflection.name, :left)
192
+ add_pending_join(joins_array, :left)
172
193
  else
173
- add_pending_join(reflection.name, :inner)
194
+ add_pending_join(joins_array, :inner)
174
195
  end
175
196
  end
176
197
 
@@ -6,7 +6,6 @@ module Refine
6
6
  include Stabilize
7
7
  include Internationalized
8
8
  include Inspector
9
- include FlatQueryTools
10
9
  # This validation structure sents `initial_query` as the method to validate against
11
10
  define_model_callbacks :initialize, only: [:after]
12
11
  after_initialize :valid?
@@ -92,10 +91,10 @@ module Refine
92
91
 
93
92
  def get_query
94
93
  raise "Initial query must exist" if initial_query.nil?
95
- if blueprint.present?
96
- @relation.where(group(make_sub_query(blueprint)))
94
+ if self.class.included_modules.include?(Refine::FlatQueryTools) && can_use_flat_query?
95
+ get_flat_query
97
96
  else
98
- @relation
97
+ get_complex_query
99
98
  end
100
99
  end
101
100
 
@@ -105,6 +104,14 @@ module Refine
105
104
  result
106
105
  end
107
106
 
107
+ def get_complex_query
108
+ if blueprint.present?
109
+ @relation.where(group(make_sub_query(blueprint)))
110
+ else
111
+ @relation
112
+ end
113
+ end
114
+
108
115
  def add_nodes_to_query(subquery:, nodes:, query_method:)
109
116
  # Apply existing nodes to existing subquery
110
117
  if subquery.present? && nodes.present?
@@ -213,6 +220,7 @@ module Refine
213
220
 
214
221
  def apply_condition(criterion)
215
222
  begin
223
+ condition = get_condition_for_criterion(criterion)
216
224
  get_condition_for_criterion(criterion)&.apply(criterion[:input], table, initial_query, false, nil)
217
225
  rescue Refine::Conditions::Errors::ConditionClauseError => e
218
226
  e.errors.each do |error|
@@ -47,7 +47,16 @@ module Refine
47
47
  else
48
48
  unless condition_already_applied?(criteria_or_conjunction)
49
49
  node = apply_flat_condition(criteria_or_conjunction)
50
- @relation = @relation.where(Arel.sql(node.to_sql))
50
+ if node.is_a?(Arel::Nodes::Grouping)
51
+ @relation = @relation.where(node)
52
+ elsif node.is_a?(Array)
53
+ error = node.filter{ |n| n.is_a?(ActiveModel::Error) }.first
54
+ if error
55
+ filter.errors.add(:base, error.full_message)
56
+ end
57
+ else
58
+ @relation = @relation.where(Arel::Nodes::Grouping.new(node))
59
+ end
51
60
  track_condition_applied(criteria_or_conjunction)
52
61
  end
53
62
  end
@@ -76,18 +85,14 @@ module Refine
76
85
  def apply_pending_joins
77
86
  if pending_joins.present?
78
87
  join_count = 0
79
- pending_joins.each do |relation, join_type|
80
- if join_type == :left
81
- @relation = @relation.left_joins(relation.to_sym).distinct
88
+ pending_joins.each do |relation, join_data|
89
+ if join_data[:type] == :left
90
+ @relation = @relation.left_joins(join_data[:joins_block]).distinct
82
91
  else
83
- @relation = @relation.joins(relation.to_sym)
92
+ @relation = @relation.joins(join_data[:joins_block]).distinct
84
93
  end
85
94
  join_count += 1
86
95
  end
87
-
88
- if join_count > 1
89
- @relation = @relation.distinct
90
- end
91
96
  end
92
97
  end
93
98
 
@@ -103,5 +108,10 @@ module Refine
103
108
  applied_conditions[criterion[:condition_id]] &&
104
109
  applied_conditions[criterion[:condition_id]].include?(criterion[:input])
105
110
  end
111
+
112
+ # Meant to be overridden by Filter classes to add or replace with custom logic
113
+ def can_use_flat_query?
114
+ !uses_or? && !uses_negative_clause? && !has_duplicate_conditions?
115
+ end
106
116
  end
107
117
  end
@@ -1,5 +1,5 @@
1
1
  module Refine
2
2
  module Rails
3
- VERSION = "2.13.7"
3
+ VERSION = "2.14.0"
4
4
  end
5
5
  end