@hammerstone/refine-stimulus
Advanced tools
Comparing version 2.2.2 to 2.2.3
@@ -1,2 +0,2 @@ | ||
import{Controller as t}from"@hotwired/stimulus";import{FetchRequest as e}from"@rails/request.js";import{delegate as i,abnegate as n}from"jquery-events-to-dom-events";import{debounce as r}from"lodash";function s(t){const e=(t.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(e)return e.replace(/_/g,"-").replace(/\//g,"--")}class a extends t{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let t=this.element;for(;t!==document.body;){const e=this.application.getControllerForElementAndIdentifier(t,"refine--state");if(e)return e;t=t.parentNode}return null}addHiddenInput(t,e){const i=document.createElement("input");return i.type="hidden",i.name=t,i.value=e||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class l extends a{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}l.values={previousCriterionId:Number};class o extends t{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let t=this.element;for(;t!==document.body;){const e=this.application.getControllerForElementAndIdentifier(t,"refine--state");if(e)return e;t=t.parentNode}return null}}o.values={criterionId:Number,input:Object};class d extends a{criterion(){const{state:t,criterionIdValue:e}=this;t.deleteCriterion(e),this.startUpdate()}}d.values={criterionId:Number};class u extends t{connect(){const t=new URLSearchParams(window.location.search);this.existingParams=t,this.existingParams.delete("stable_id")}search(t){t.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const t=this,{blueprint:e}=t.stateController;return Promise.resolve(t.stabilizeFilterController.validateBlueprint(e)).then(function(i){i.stableId?t.redirectToStableId(i.stableId):t.fetchAndRenderInvalidFilter(e)})}catch(t){return Promise.reject(t)}}addHiddenInput(t){let{name:e,value:i}=t;const n=document.createElement("input");n.type="hidden",n.name=e,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(t){const e=new URLSearchParams;t&&e.append("stable_id",t);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(e)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(t){try{const i=this,n=new e("POST",i.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:i.stateController.filterName,blueprint:JSON.stringify(t),id_suffix:i.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(t){return Promise.reject(t)}}}u.values={submitUrl:String},u.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),i}t.prototype=window.Event.prototype,window.CustomEvent=t}();const c=(t,e,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:e,filterName:i}});t.dispatchEvent(n)},h=(t,e)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});t.dispatchEvent(i)},p=(t,e,i)=>{var n;const r=null==i?void 0:i.component,s=(null==i?void 0:i.meta)||{clauses:[],options:{}},a=(null==i?void 0:i.refinements)||[],{clauses:l,options:o}=s;let d={clause:null==(n=l[0])?void 0:n.id,selected:"option-condition"===r?[o[0].id]:void 0};return a.forEach(t=>{var e;const{meta:i,component:n}=t,{clauses:r,options:s}=i;d[t.id]={clause:r[0].id,selected:"option-condition"===n?[null==(e=s[0])?void 0:e.id]:void 0}}),{depth:e,type:"criterion",condition_id:t,input:d}};class b extends t{connect(){this.element.refineStateController=this,this.changeDelegate=i("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((t,e)=>(t[e.id]=e,t),{}),this.loadingTimeout=null,h(this.element,this.blueprint)}disconnect(){n("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(t){return this.conditionsLookup[t]}updateStableId(t){t!==this.stableId&&(this.stableId=t)}addGroup(){const{conditions:t}=this,e=t[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(p(e.id,1,e)),h(this.element,this.blueprint)}addCriterion(t){const{blueprint:e,conditions:i}=this,n=i[0];var r;e.splice(t+1,0,{depth:r=void 0===r?1:r,type:"conjunction",word:"and"},p(n.id,1,n)),h(this.element,this.blueprint)}deleteCriterion(t){const{blueprint:e}=this,i=e[t-1],n=e[t+1],r=i&&"or"===i.word,s=n&&"or"===n.word||!n,a=r||!i,l=a&&s;i||n?e.splice(l&&r?t-1:l&&!i||a&&!s?t:t-1,2):this.blueprint=[],h(this.element,this.blueprint)}replaceCriterion(t,e,i){const n=this.blueprint[t];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(p));this.blueprint[t]=p(e,n.depth,i),h(this.element,this.blueprint)}updateInput(t,e,i){const{blueprint:n}=this,r=n[t],s=(i=i||"input").split(", ");s.length>1?r[s[0]][s[1]]={...r[s[0]][s[1]],...e}:r[i]={...r[i],...e},h(this.element,this.blueprint)}}b.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},b.targets=["loading"];class m extends t{connect(){this.idValue&&(t=>{const e=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(e)})()}updateStableIdField(t){if(t.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:e}=t,{stableId:i}=e;this.stableIdFieldTarget.value=i}}activateSaveLink(t){const{detail:e}=t,{stableId:i}=e;if(t.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const t=new URL(this.enabledSaveLinkTarget.href);t.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",t),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}m.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],m.values={id:Number,stableId:String,filterName:String};class f extends t{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(t){try{const e=this;(t=>{const e=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});window.dispatchEvent(e)})(e.blueprint);const i=t.detail.blueprint;return Promise.resolve(e.validateBlueprint(i)).then(function(t){if(t.stableId)e.stableIdValue=t.stableId,c(e.element,e.stableIdValue,e.filterNameValue),c(window,e.stableIdValue,e.filterNameValue);else{const{errors:e}=t;(t=>{let{blueprint:e,errors:i}=t;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:e,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:e})}})}catch(t){return Promise.reject(t)}}validateBlueprint(t){try{var e;const i=this;let n=JSON.stringify({blueprint:t,filter:i.filterNameValue}),r=null==(e=document.querySelector("meta[name='csrf-token']"))?void 0:e.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r}})).then(function(t){return Promise.resolve(t.json()).then(function(e){return t.ok?{stableId:e.filter_id}:{errors:e.errors}})})}catch(t){return Promise.reject(t)}}}f.values={stableId:String,updateStableIdUrl:String,filterName:String},f.targets=[];class v extends a{initialize(){this.updateBlueprint=r((t,e,i)=>{this.value(t,e,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){a.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(t){const{criterionIdValue:e,state:i}=this;i.updateInput(e,{id:t.target.value},t.target.dataset.inputId),this.submitForm()}clause(t){const{criterionIdValue:e,state:i}=this;i.updateInput(e,{clause:t.target.value},t.target.dataset.inputId),this.submitForm()}selected(t){const{target:e}=t,i=Array.prototype.slice.call(e.options).filter(t=>t.selected).map(t=>t.value);this.value(t,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(t,e,i){const{criterionIdValue:n,state:r}=this,s=t.target.dataset;r.updateInput(n,{[i=i||s.inputKey||"value"]:e=e||t.target.value},s.inputId)}date(t){const{picker:e}=t.detail,i=e.startDate.format("YYYY-MM-DD");this.value(t,i),this.submitForm()}createStableId(t,e){var i;const{state:n}=this;let r=JSON.stringify({blueprint:t,filter:e}),s=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:r,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":s},success:function(t){n.updateStableId(t.filter_id)}})}condition(t){const{criterionIdValue:e,state:i}=this,n=t.target.value,r=this.state.conditionConfigFor(n);i.replaceCriterion(e,n,r),this.submitForm()}cancelEnter(t){"Enter"===t.code&&(t.preventDefault(),t.stopPropagation())}}v.values={criterionId:Number,stableId:String};const g=[[l,"refine/add-controller.js"],[o,"refine/defaults-controller.js"],[d,"refine/delete-controller.js"],[a,"refine/form-controller.js"],[u,"refine/search-filter-controller.js"],[b,"refine/state-controller.js"],[m,"refine/stored-filter-controller.js"],[f,"refine/stabilize-filter-controller.js"],[v,"refine/update-controller.js"]].map(function(t){const e=t[0];return{identifier:s(t[1]),controllerConstructor:e}});export{l as AddController,o as DefaultsController,d as DeleteController,a as FormController,u as SearchFilterController,f as StabilizeFilterController,b as StateController,m as StoredFilterController,v as UpdateController,g as controllerDefinitions}; | ||
import{Controller as e}from"@hotwired/stimulus";import{FetchRequest as t}from"@rails/request.js";import{delegate as i,abnegate as n}from"jquery-events-to-dom-events";import{debounce as a}from"lodash";import r from"jquery";import"daterangepicker";function s(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class l extends e{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class o extends l{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}o.values={previousCriterionId:Number};class d extends e{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}d.values={criterionId:Number,input:Object};class u extends l{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}u.values={criterionId:Number};class c extends e{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const e=this,{blueprint:t}=e.stateController;return Promise.resolve(e.stabilizeFilterController.validateBlueprint(t)).then(function(i){i.stableId?e.redirectToStableId(i.stableId):e.fetchAndRenderInvalidFilter(t)})}catch(e){return Promise.reject(e)}}addHiddenInput(e){let{name:t,value:i}=e;const n=document.createElement("input");n.type="hidden",n.name=t,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(t)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(e){try{const i=this,n=new t("POST",i.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:i.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:i.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(e){return Promise.reject(e)}}}c.values={submitUrl:String},c.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const h=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},p=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},m=(e,t,i)=>{var n;const a=null==i?void 0:i.component,r=(null==i?void 0:i.meta)||{clauses:[],options:{}},s=(null==i?void 0:i.refinements)||[],{clauses:l,options:o}=r;let d={clause:null==(n=l[0])?void 0:n.id,selected:"option-condition"===a?[o[0].id]:void 0};return s.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:a,options:r}=i;d[e.id]={clause:a[0].id,selected:"option-condition"===n?[null==(t=r[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class b extends e{connect(){this.element.refineStateController=this,this.changeDelegate=i("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,p(this.element,this.blueprint)}disconnect(){n("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(m(t.id,1,t)),p(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var a;t.splice(e+1,0,{depth:a=void 0===a?1:a,type:"conjunction",word:"and"},m(n.id,1,n)),p(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],a=i&&"or"===i.word,r=n&&"or"===n.word||!n,s=a||!i,l=s&&r;i||n?t.splice(l&&a?e-1:l&&!i||s&&!r?e:e-1,2):this.blueprint=[],p(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(m));this.blueprint[e]=m(t,n.depth,i),p(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,a=n[e],r=(i=i||"input").split(", ");r.length>1?a[r[0]][r[1]]={...a[r[0]][r[1]],...t}:a[i]={...a[i],...t},p(this.element,this.blueprint)}}b.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},b.targets=["loading"];class f extends e{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}f.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],f.values={id:Number,stableId:String,filterName:String};class g extends e{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(e){try{const t=this;(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});window.dispatchEvent(t)})(t.blueprint);const i=e.detail.blueprint;return Promise.resolve(t.validateBlueprint(i)).then(function(e){if(e.stableId)t.stableIdValue=e.stableId,h(t.element,t.stableIdValue,t.filterNameValue),h(window,t.stableIdValue,t.filterNameValue);else{const{errors:t}=e;(e=>{let{blueprint:t,errors:i}=e;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:t})}})}catch(e){return Promise.reject(e)}}validateBlueprint(e){try{var t;const i=this;let n=JSON.stringify({blueprint:e,filter:i.filterNameValue}),a=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":a}})).then(function(e){return Promise.resolve(e.json()).then(function(t){return e.ok?{stableId:t.filter_id}:{errors:t.errors}})})}catch(e){return Promise.reject(e)}}}g.values={stableId:String,updateStableIdUrl:String,filterName:String},g.targets=[];class v extends l{initialize(){this.updateBlueprint=a((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){l.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:a}=this,r=e.target.dataset;a.updateInput(n,{[i=i||r.inputKey||"value"]:t=t||e.target.value},r.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let a=JSON.stringify({blueprint:e,filter:t}),r=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:a,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,a=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,a),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}v.values={criterionId:Number,stableId:String},require("daterangepicker/daterangepicker.css");class S extends e{connect(){this.initPluginInstance()}disconnect(){this.teardownPluginInstance()}clearDate(e){e.preventDefault(),r(this.fieldTarget).val("")}applyDateToField(e,t){const i=this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY";r(this.fieldTarget).val(t.startDate.format(i)),r(this.fieldTarget).trigger("change",t)}showTimeZoneButtons(e){e.preventDefault(),r(this.currentTimeZoneWrapperTarget).toggleClass("hidden"),r(this.timeZoneButtonsTarget).toggleClass("hidden")}showTimeZoneSelectWrapper(e){e.preventDefault(),r(this.timeZoneButtonsTarget).toggleClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&r(this.timeZoneSelectWrapperTarget).toggleClass("hidden")}resetTimeZoneUI(e){e&&e.preventDefault(),r(this.currentTimeZoneWrapperTarget).removeClass("hidden"),r(this.timeZoneButtonsTarget).addClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&r(this.timeZoneSelectWrapperTarget).addClass("hidden")}setTimeZone(e){e.preventDefault();const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target.dataset;r(this.timeZoneFieldTarget).val(i),r(t).text(i),r(".time-zone-button").removeClass("button").addClass("button-alternative"),r(e.target).removeClass("button-alternative").addClass("button"),this.resetTimeZoneUI()}initPluginInstance(){r(this.fieldTarget).daterangepicker({singleDatePicker:!0,timePicker:this.includeTimeValue,timePickerIncrement:5,autoUpdateInput:!1,minDate:!!this.futureOnlyValue&&new Date,locale:{cancelLabel:this.cancelButtonLabelValue,applyLabel:this.applyButtonLabelValue,format:this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY"},parentEl:r(this.element),drops:this.dropsValue?this.dropsValue:"down"}),r(this.fieldTarget).on("apply.daterangepicker",this.applyDateToField.bind(this)),r(this.fieldTarget).on("cancel.daterangepicker",this.clearDate.bind(this)),this.pluginMainEl=this.fieldTarget,this.plugin=r(this.pluginMainEl).data("daterangepicker"),this.includeTimeValue&&this.hasTimeZoneSelectWrapperTarget&&(this.timeZoneSelect=this.timeZoneSelectWrapperTarget.querySelector("select.select2"),r(this.timeZoneSelect).select2({width:"style"}),r(this.timeZoneSelect).on("change.select2",e=>{const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target;r(this.timeZoneFieldTarget).val(i),r(t).text(i);const n=r(".selected-option-time-zone-button");this.defaultTimeZonesValue.includes(i)?(r(".time-zone-button").removeClass("button").addClass("button-alternative"),n.addClass("hidden").attr("hidden",!0),r('a[data-value="'+i+'"').removeClass("button-alternative").addClass("button")):(r(".time-zone-button").removeClass("button").addClass("button-alternative"),n.text(i),n.attr("data-value",i).removeAttr("hidden"),n.removeClass(["hidden","button-alternative"]).addClass("button")),this.resetTimeZoneUI()}))}teardownPluginInstance(){void 0!==this.plugin&&(r(this.pluginMainEl).off("apply.daterangepicker"),r(this.pluginMainEl).off("cancel.daterangepicker"),this.plugin.remove(),this.includeTimeValue&&r(this.timeZoneSelect).select2("destroy"))}}S.targets=["field","clearButton","currentTimeZoneWrapper","timeZoneButtons","timeZoneSelectWrapper","timeZoneField"],S.values={includeTime:Boolean,defaultTimeZones:Array,futureOnly:Boolean,drops:String,cancelButtonLabel:{type:String,default:"Cancel"},applyButtonLabel:{type:String,default:"Apply"}};const I=[[o,"refine/add-controller.js"],[d,"refine/defaults-controller.js"],[u,"refine/delete-controller.js"],[l,"refine/form-controller.js"],[c,"refine/search-filter-controller.js"],[b,"refine/state-controller.js"],[f,"refine/stored-filter-controller.js"],[g,"refine/stabilize-filter-controller.js"],[v,"refine/update-controller.js"],[S,"refine/date-controller.js"]].map(function(e){const t=e[0];return{identifier:s(e[1]),controllerConstructor:t}});export{o as AddController,S as DateController,d as DefaultsController,u as DeleteController,l as FormController,c as SearchFilterController,g as StabilizeFilterController,b as StateController,f as StoredFilterController,v as UpdateController,I as controllerDefinitions}; | ||
//# sourceMappingURL=refine-stimulus.esm.js.map |
@@ -1,2 +0,2 @@ | ||
var e=require("@hotwired/stimulus"),t=require("@rails/request.js"),i=require("jquery-events-to-dom-events"),n=require("lodash");function r(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class s extends e.Controller{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class l extends s{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}l.values={previousCriterionId:Number};class a extends e.Controller{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}a.values={criterionId:Number,input:Object};class o extends s{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}o.values={criterionId:Number};class d extends e.Controller{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const e=this,{blueprint:t}=e.stateController;return Promise.resolve(e.stabilizeFilterController.validateBlueprint(t)).then(function(i){i.stableId?e.redirectToStableId(i.stableId):e.fetchAndRenderInvalidFilter(t)})}catch(e){return Promise.reject(e)}}addHiddenInput(e){let{name:t,value:i}=e;const n=document.createElement("input");n.type="hidden",n.name=t,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(t)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(e){try{const i=this,n=new t.FetchRequest("POST",i.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:i.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:i.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(e){return Promise.reject(e)}}}d.values={submitUrl:String},d.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const u=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},c=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},h=(e,t,i)=>{var n;const r=null==i?void 0:i.component,s=(null==i?void 0:i.meta)||{clauses:[],options:{}},l=(null==i?void 0:i.refinements)||[],{clauses:a,options:o}=s;let d={clause:null==(n=a[0])?void 0:n.id,selected:"option-condition"===r?[o[0].id]:void 0};return l.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:r,options:s}=i;d[e.id]={clause:r[0].id,selected:"option-condition"===n?[null==(t=s[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class p extends e.Controller{connect(){this.element.refineStateController=this,this.changeDelegate=i.delegate("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,c(this.element,this.blueprint)}disconnect(){i.abnegate("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(h(t.id,1,t)),c(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var r;t.splice(e+1,0,{depth:r=void 0===r?1:r,type:"conjunction",word:"and"},h(n.id,1,n)),c(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],r=i&&"or"===i.word,s=n&&"or"===n.word||!n,l=r||!i,a=l&&s;i||n?t.splice(a&&r?e-1:a&&!i||l&&!s?e:e-1,2):this.blueprint=[],c(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(h));this.blueprint[e]=h(t,n.depth,i),c(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,r=n[e],s=(i=i||"input").split(", ");s.length>1?r[s[0]][s[1]]={...r[s[0]][s[1]],...t}:r[i]={...r[i],...t},c(this.element,this.blueprint)}}p.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},p.targets=["loading"];class b extends e.Controller{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}b.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],b.values={id:Number,stableId:String,filterName:String};class m extends e.Controller{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(e){try{const t=this;(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});window.dispatchEvent(t)})(t.blueprint);const i=e.detail.blueprint;return Promise.resolve(t.validateBlueprint(i)).then(function(e){if(e.stableId)t.stableIdValue=e.stableId,u(t.element,t.stableIdValue,t.filterNameValue),u(window,t.stableIdValue,t.filterNameValue);else{const{errors:t}=e;(e=>{let{blueprint:t,errors:i}=e;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:t})}})}catch(e){return Promise.reject(e)}}validateBlueprint(e){try{var t;const i=this;let n=JSON.stringify({blueprint:e,filter:i.filterNameValue}),r=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r}})).then(function(e){return Promise.resolve(e.json()).then(function(t){return e.ok?{stableId:t.filter_id}:{errors:t.errors}})})}catch(e){return Promise.reject(e)}}}m.values={stableId:String,updateStableIdUrl:String,filterName:String},m.targets=[];class f extends s{initialize(){this.updateBlueprint=n.debounce((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){s.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:r}=this,s=e.target.dataset;r.updateInput(n,{[i=i||s.inputKey||"value"]:t=t||e.target.value},s.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let r=JSON.stringify({blueprint:e,filter:t}),s=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:r,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":s},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,r=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,r),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}f.values={criterionId:Number,stableId:String};const v=[[l,"refine/add-controller.js"],[a,"refine/defaults-controller.js"],[o,"refine/delete-controller.js"],[s,"refine/form-controller.js"],[d,"refine/search-filter-controller.js"],[p,"refine/state-controller.js"],[b,"refine/stored-filter-controller.js"],[m,"refine/stabilize-filter-controller.js"],[f,"refine/update-controller.js"]].map(function(e){const t=e[0];return{identifier:r(e[1]),controllerConstructor:t}});exports.AddController=l,exports.DefaultsController=a,exports.DeleteController=o,exports.FormController=s,exports.SearchFilterController=d,exports.StabilizeFilterController=m,exports.StateController=p,exports.StoredFilterController=b,exports.UpdateController=f,exports.controllerDefinitions=v; | ||
var e=require("@hotwired/stimulus"),t=require("@rails/request.js"),i=require("jquery-events-to-dom-events"),n=require("lodash"),r=require("jquery");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("daterangepicker");var l=a(r);function s(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class o extends e.Controller{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class d extends o{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}d.values={previousCriterionId:Number};class u extends e.Controller{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}u.values={criterionId:Number,input:Object};class c extends o{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}c.values={criterionId:Number};class h extends e.Controller{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const e=this,{blueprint:t}=e.stateController;return Promise.resolve(e.stabilizeFilterController.validateBlueprint(t)).then(function(i){i.stableId?e.redirectToStableId(i.stableId):e.fetchAndRenderInvalidFilter(t)})}catch(e){return Promise.reject(e)}}addHiddenInput(e){let{name:t,value:i}=e;const n=document.createElement("input");n.type="hidden",n.name=t,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(t)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(e){try{const i=this,n=new t.FetchRequest("POST",i.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:i.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:i.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(e){return Promise.reject(e)}}}h.values={submitUrl:String},h.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const p=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},m=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},f=(e,t,i)=>{var n;const r=null==i?void 0:i.component,a=(null==i?void 0:i.meta)||{clauses:[],options:{}},l=(null==i?void 0:i.refinements)||[],{clauses:s,options:o}=a;let d={clause:null==(n=s[0])?void 0:n.id,selected:"option-condition"===r?[o[0].id]:void 0};return l.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:r,options:a}=i;d[e.id]={clause:r[0].id,selected:"option-condition"===n?[null==(t=a[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class b extends e.Controller{connect(){this.element.refineStateController=this,this.changeDelegate=i.delegate("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,m(this.element,this.blueprint)}disconnect(){i.abnegate("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(f(t.id,1,t)),m(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var r;t.splice(e+1,0,{depth:r=void 0===r?1:r,type:"conjunction",word:"and"},f(n.id,1,n)),m(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],r=i&&"or"===i.word,a=n&&"or"===n.word||!n,l=r||!i,s=l&&a;i||n?t.splice(s&&r?e-1:s&&!i||l&&!a?e:e-1,2):this.blueprint=[],m(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(f));this.blueprint[e]=f(t,n.depth,i),m(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,r=n[e],a=(i=i||"input").split(", ");a.length>1?r[a[0]][a[1]]={...r[a[0]][a[1]],...t}:r[i]={...r[i],...t},m(this.element,this.blueprint)}}b.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},b.targets=["loading"];class g extends e.Controller{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}g.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],g.values={id:Number,stableId:String,filterName:String};class v extends e.Controller{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(e){try{const t=this;(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});window.dispatchEvent(t)})(t.blueprint);const i=e.detail.blueprint;return Promise.resolve(t.validateBlueprint(i)).then(function(e){if(e.stableId)t.stableIdValue=e.stableId,p(t.element,t.stableIdValue,t.filterNameValue),p(window,t.stableIdValue,t.filterNameValue);else{const{errors:t}=e;(e=>{let{blueprint:t,errors:i}=e;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:t})}})}catch(e){return Promise.reject(e)}}validateBlueprint(e){try{var t;const i=this;let n=JSON.stringify({blueprint:e,filter:i.filterNameValue}),r=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r}})).then(function(e){return Promise.resolve(e.json()).then(function(t){return e.ok?{stableId:t.filter_id}:{errors:t.errors}})})}catch(e){return Promise.reject(e)}}}v.values={stableId:String,updateStableIdUrl:String,filterName:String},v.targets=[];class S extends o{initialize(){this.updateBlueprint=n.debounce((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){o.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:r}=this,a=e.target.dataset;r.updateInput(n,{[i=i||a.inputKey||"value"]:t=t||e.target.value},a.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let r=JSON.stringify({blueprint:e,filter:t}),a=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:r,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":a},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,r=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,r),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}S.values={criterionId:Number,stableId:String},require("daterangepicker/daterangepicker.css");class C extends e.Controller{connect(){this.initPluginInstance()}disconnect(){this.teardownPluginInstance()}clearDate(e){e.preventDefault(),l.default(this.fieldTarget).val("")}applyDateToField(e,t){const i=this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY";l.default(this.fieldTarget).val(t.startDate.format(i)),l.default(this.fieldTarget).trigger("change",t)}showTimeZoneButtons(e){e.preventDefault(),l.default(this.currentTimeZoneWrapperTarget).toggleClass("hidden"),l.default(this.timeZoneButtonsTarget).toggleClass("hidden")}showTimeZoneSelectWrapper(e){e.preventDefault(),l.default(this.timeZoneButtonsTarget).toggleClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&l.default(this.timeZoneSelectWrapperTarget).toggleClass("hidden")}resetTimeZoneUI(e){e&&e.preventDefault(),l.default(this.currentTimeZoneWrapperTarget).removeClass("hidden"),l.default(this.timeZoneButtonsTarget).addClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&l.default(this.timeZoneSelectWrapperTarget).addClass("hidden")}setTimeZone(e){e.preventDefault();const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target.dataset;l.default(this.timeZoneFieldTarget).val(i),l.default(t).text(i),l.default(".time-zone-button").removeClass("button").addClass("button-alternative"),l.default(e.target).removeClass("button-alternative").addClass("button"),this.resetTimeZoneUI()}initPluginInstance(){l.default(this.fieldTarget).daterangepicker({singleDatePicker:!0,timePicker:this.includeTimeValue,timePickerIncrement:5,autoUpdateInput:!1,minDate:!!this.futureOnlyValue&&new Date,locale:{cancelLabel:this.cancelButtonLabelValue,applyLabel:this.applyButtonLabelValue,format:this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY"},parentEl:l.default(this.element),drops:this.dropsValue?this.dropsValue:"down"}),l.default(this.fieldTarget).on("apply.daterangepicker",this.applyDateToField.bind(this)),l.default(this.fieldTarget).on("cancel.daterangepicker",this.clearDate.bind(this)),this.pluginMainEl=this.fieldTarget,this.plugin=l.default(this.pluginMainEl).data("daterangepicker"),this.includeTimeValue&&this.hasTimeZoneSelectWrapperTarget&&(this.timeZoneSelect=this.timeZoneSelectWrapperTarget.querySelector("select.select2"),l.default(this.timeZoneSelect).select2({width:"style"}),l.default(this.timeZoneSelect).on("change.select2",e=>{const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target;l.default(this.timeZoneFieldTarget).val(i),l.default(t).text(i);const n=l.default(".selected-option-time-zone-button");this.defaultTimeZonesValue.includes(i)?(l.default(".time-zone-button").removeClass("button").addClass("button-alternative"),n.addClass("hidden").attr("hidden",!0),l.default('a[data-value="'+i+'"').removeClass("button-alternative").addClass("button")):(l.default(".time-zone-button").removeClass("button").addClass("button-alternative"),n.text(i),n.attr("data-value",i).removeAttr("hidden"),n.removeClass(["hidden","button-alternative"]).addClass("button")),this.resetTimeZoneUI()}))}teardownPluginInstance(){void 0!==this.plugin&&(l.default(this.pluginMainEl).off("apply.daterangepicker"),l.default(this.pluginMainEl).off("cancel.daterangepicker"),this.plugin.remove(),this.includeTimeValue&&l.default(this.timeZoneSelect).select2("destroy"))}}C.targets=["field","clearButton","currentTimeZoneWrapper","timeZoneButtons","timeZoneSelectWrapper","timeZoneField"],C.values={includeTime:Boolean,defaultTimeZones:Array,futureOnly:Boolean,drops:String,cancelButtonLabel:{type:String,default:"Cancel"},applyButtonLabel:{type:String,default:"Apply"}};const I=[[d,"refine/add-controller.js"],[u,"refine/defaults-controller.js"],[c,"refine/delete-controller.js"],[o,"refine/form-controller.js"],[h,"refine/search-filter-controller.js"],[b,"refine/state-controller.js"],[g,"refine/stored-filter-controller.js"],[v,"refine/stabilize-filter-controller.js"],[S,"refine/update-controller.js"],[C,"refine/date-controller.js"]].map(function(e){const t=e[0];return{identifier:s(e[1]),controllerConstructor:t}});exports.AddController=d,exports.DateController=C,exports.DefaultsController=u,exports.DeleteController=c,exports.FormController=o,exports.SearchFilterController=h,exports.StabilizeFilterController=v,exports.StateController=b,exports.StoredFilterController=g,exports.UpdateController=S,exports.controllerDefinitions=I; | ||
//# sourceMappingURL=refine-stimulus.js.map |
@@ -1,2 +0,2 @@ | ||
import{Controller as t}from"@hotwired/stimulus";import{FetchRequest as e}from"@rails/request.js";import{delegate as i,abnegate as n}from"jquery-events-to-dom-events";import{debounce as s}from"lodash";function r(t){const e=(t.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(e)return e.replace(/_/g,"-").replace(/\//g,"--")}class a extends t{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let t=this.element;for(;t!==document.body;){const e=this.application.getControllerForElementAndIdentifier(t,"refine--state");if(e)return e;t=t.parentNode}return null}addHiddenInput(t,e){const i=document.createElement("input");return i.type="hidden",i.name=t,i.value=e||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class l extends a{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}l.values={previousCriterionId:Number};class o extends t{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let t=this.element;for(;t!==document.body;){const e=this.application.getControllerForElementAndIdentifier(t,"refine--state");if(e)return e;t=t.parentNode}return null}}o.values={criterionId:Number,input:Object};class d extends a{criterion(){const{state:t,criterionIdValue:e}=this;t.deleteCriterion(e),this.startUpdate()}}function u(){return u=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(t[n]=i[n])}return t},u.apply(this,arguments)}d.values={criterionId:Number};class c extends t{connect(){const t=new URLSearchParams(window.location.search);this.existingParams=t,this.existingParams.delete("stable_id")}search(t){t.preventDefault(),this.submitFilter(),document.activeElement.blur()}async submitFilter(){const{blueprint:t}=this.stateController,e=await this.stabilizeFilterController.validateBlueprint(t);e.stableId?this.redirectToStableId(e.stableId):this.fetchAndRenderInvalidFilter(t)}addHiddenInput({name:t,value:e}){const i=document.createElement("input");i.type="hidden",i.name=t,i.value=e,this.submissionFormTarget.appendChild(i)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(t){const e=new URLSearchParams;t&&e.append("stable_id",t);const i=new URLSearchParams(u({},Object.fromEntries(this.existingParams),Object.fromEntries(e))).toString(),n=`${window.location.pathname}?${i}`;history.pushState({},document.title,n),window.location.reload()}async fetchAndRenderInvalidFilter(t){const i=new e("POST",this.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:this.stateController.filterName,blueprint:JSON.stringify(t),id_suffix:this.stateController.idSuffix})});await i.perform()}}c.values={submitUrl:String},c.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),i}t.prototype=window.Event.prototype,window.CustomEvent=t}();const h=(t,e,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:e,filterName:i}});t.dispatchEvent(n)},p=(t,e)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});t.dispatchEvent(i)},b=(t,e,i)=>{var n;const s=null==i?void 0:i.component,r=(null==i?void 0:i.meta)||{clauses:[],options:{}},a=(null==i?void 0:i.refinements)||[],{clauses:l,options:o}=r;let d={clause:null==(n=l[0])?void 0:n.id,selected:"option-condition"===s?[o[0].id]:void 0};return a.forEach(t=>{var e;const{meta:i,component:n}=t,{clauses:s,options:r}=i;d[t.id]={clause:s[0].id,selected:"option-condition"===n?[null==(e=r[0])?void 0:e.id]:void 0}}),{depth:e,type:"criterion",condition_id:t,input:d}};class m extends t{connect(){this.element.refineStateController=this,this.changeDelegate=i("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((t,e)=>(t[e.id]=e,t),{}),this.loadingTimeout=null,p(this.element,this.blueprint)}disconnect(){n("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(t){return this.conditionsLookup[t]}updateStableId(t){t!==this.stableId&&(this.stableId=t)}addGroup(){const{conditions:t}=this,e=t[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(b(e.id,1,e)),p(this.element,this.blueprint)}addCriterion(t){const{blueprint:e,conditions:i}=this,n=i[0];var s;e.splice(t+1,0,{depth:s=void 0===s?1:s,type:"conjunction",word:"and"},b(n.id,1,n)),p(this.element,this.blueprint)}deleteCriterion(t){const{blueprint:e}=this,i=e[t-1],n=e[t+1],s=i&&"or"===i.word,r=n&&"or"===n.word||!n,a=s||!i,l=a&&r;i||n?e.splice(l&&s?t-1:l&&!i||a&&!r?t:t-1,2):this.blueprint=[],p(this.element,this.blueprint)}replaceCriterion(t,e,i){const n=this.blueprint[t];if("criterion"!==n.type)throw new Error(`You can't call updateConditionId on a non-criterion type. Trying to update ${JSON.stringify(b)}`);this.blueprint[t]=b(e,n.depth,i),p(this.element,this.blueprint)}updateInput(t,e,i){const{blueprint:n}=this,s=n[t],r=(i=i||"input").split(", ");r.length>1?s[r[0]][r[1]]=u({},s[r[0]][r[1]],e):s[i]=u({},s[i],e),p(this.element,this.blueprint)}}m.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},m.targets=["loading"];class f extends t{connect(){this.idValue&&(t=>{const e=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(e)})()}updateStableIdField(t){if(t.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:e}=t,{stableId:i}=e;this.stableIdFieldTarget.value=i}}activateSaveLink(t){const{detail:e}=t,{stableId:i}=e;if(t.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const t=new URL(this.enabledSaveLinkTarget.href);t.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",t),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}f.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],f.values={id:Number,stableId:String,filterName:String};class v extends t{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}async updateStableId(t){(t=>{const e=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:this.blueprint}});window.dispatchEvent(e)})();const e=t.detail.blueprint,i=await this.validateBlueprint(e);if(i.stableId)this.stableIdValue=i.stableId,h(this.element,this.stableIdValue,this.filterNameValue),h(window,this.stableIdValue,this.filterNameValue);else{const{errors:t}=i;(({blueprint:t,errors:e})=>{const i=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:e}});window.dispatchEvent(i)})({blueprint:e,errors:t})}}async validateBlueprint(t){var e;let i=JSON.stringify({blueprint:t,filter:this.filterNameValue}),n=null==(e=document.querySelector("meta[name='csrf-token']"))?void 0:e.content;const s=await fetch(this.updateStableIdUrlValue,{method:"PUT",body:i,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":n}}),r=await s.json();return s.ok?{stableId:r.filter_id}:{errors:r.errors}}}v.values={stableId:String,updateStableIdUrl:String,filterName:String},v.targets=[];class g extends a{initialize(){this.updateBlueprint=s((t,e,i)=>{this.value(t,e,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){a.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(t){const{criterionIdValue:e,state:i}=this;i.updateInput(e,{id:t.target.value},t.target.dataset.inputId),this.submitForm()}clause(t){const{criterionIdValue:e,state:i}=this;i.updateInput(e,{clause:t.target.value},t.target.dataset.inputId),this.submitForm()}selected(t){const{target:e}=t,i=Array.prototype.slice.call(e.options).filter(t=>t.selected).map(t=>t.value);this.value(t,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(t,e,i){const{criterionIdValue:n,state:s}=this,r=t.target.dataset;s.updateInput(n,{[i=i||r.inputKey||"value"]:e=e||t.target.value},r.inputId)}date(t){const{picker:e}=t.detail,i=e.startDate.format("YYYY-MM-DD");this.value(t,i),this.submitForm()}createStableId(t,e){var i;const{state:n}=this;let s=JSON.stringify({blueprint:t,filter:e}),r=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:s,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r},success:function(t){n.updateStableId(t.filter_id)}})}condition(t){const{criterionIdValue:e,state:i}=this,n=t.target.value,s=this.state.conditionConfigFor(n);i.replaceCriterion(e,n,s),this.submitForm()}cancelEnter(t){"Enter"===t.code&&(t.preventDefault(),t.stopPropagation())}}g.values={criterionId:Number,stableId:String};const I=[[l,"refine/add-controller.js"],[o,"refine/defaults-controller.js"],[d,"refine/delete-controller.js"],[a,"refine/form-controller.js"],[c,"refine/search-filter-controller.js"],[m,"refine/state-controller.js"],[f,"refine/stored-filter-controller.js"],[v,"refine/stabilize-filter-controller.js"],[g,"refine/update-controller.js"]].map(function(t){const e=t[0];return{identifier:r(t[1]),controllerConstructor:e}});export{l as AddController,o as DefaultsController,d as DeleteController,a as FormController,c as SearchFilterController,v as StabilizeFilterController,m as StateController,f as StoredFilterController,g as UpdateController,I as controllerDefinitions}; | ||
import{Controller as e}from"@hotwired/stimulus";import{FetchRequest as t}from"@rails/request.js";import{delegate as i,abnegate as n}from"jquery-events-to-dom-events";import{debounce as a}from"lodash";import r from"jquery";import"daterangepicker";function s(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class l extends e{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class o extends l{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}o.values={previousCriterionId:Number};class d extends e{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}d.values={criterionId:Number,input:Object};class u extends l{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}function c(){return c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i=arguments[t];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e},c.apply(this,arguments)}u.values={criterionId:Number};class h extends e{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}async submitFilter(){const{blueprint:e}=this.stateController,t=await this.stabilizeFilterController.validateBlueprint(e);t.stableId?this.redirectToStableId(t.stableId):this.fetchAndRenderInvalidFilter(e)}addHiddenInput({name:e,value:t}){const i=document.createElement("input");i.type="hidden",i.name=e,i.value=t,this.submissionFormTarget.appendChild(i)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams(c({},Object.fromEntries(this.existingParams),Object.fromEntries(t))).toString(),n=`${window.location.pathname}?${i}`;history.pushState({},document.title,n),window.location.reload()}async fetchAndRenderInvalidFilter(e){const i=new t("POST",this.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:this.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:this.stateController.idSuffix})});await i.perform()}}h.values={submitUrl:String},h.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const p=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},m=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},b=(e,t,i)=>{var n;const a=null==i?void 0:i.component,r=(null==i?void 0:i.meta)||{clauses:[],options:{}},s=(null==i?void 0:i.refinements)||[],{clauses:l,options:o}=r;let d={clause:null==(n=l[0])?void 0:n.id,selected:"option-condition"===a?[o[0].id]:void 0};return s.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:a,options:r}=i;d[e.id]={clause:a[0].id,selected:"option-condition"===n?[null==(t=r[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class f extends e{connect(){this.element.refineStateController=this,this.changeDelegate=i("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,m(this.element,this.blueprint)}disconnect(){n("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(b(t.id,1,t)),m(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var a;t.splice(e+1,0,{depth:a=void 0===a?1:a,type:"conjunction",word:"and"},b(n.id,1,n)),m(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],a=i&&"or"===i.word,r=n&&"or"===n.word||!n,s=a||!i,l=s&&r;i||n?t.splice(l&&a?e-1:l&&!i||s&&!r?e:e-1,2):this.blueprint=[],m(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error(`You can't call updateConditionId on a non-criterion type. Trying to update ${JSON.stringify(b)}`);this.blueprint[e]=b(t,n.depth,i),m(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,a=n[e],r=(i=i||"input").split(", ");r.length>1?a[r[0]][r[1]]=c({},a[r[0]][r[1]],t):a[i]=c({},a[i],t),m(this.element,this.blueprint)}}f.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},f.targets=["loading"];class g extends e{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}g.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],g.values={id:Number,stableId:String,filterName:String};class v extends e{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}async updateStableId(e){(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:this.blueprint}});window.dispatchEvent(t)})();const t=e.detail.blueprint,i=await this.validateBlueprint(t);if(i.stableId)this.stableIdValue=i.stableId,p(this.element,this.stableIdValue,this.filterNameValue),p(window,this.stableIdValue,this.filterNameValue);else{const{errors:e}=i;(({blueprint:e,errors:t})=>{const i=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:e,errors:t}});window.dispatchEvent(i)})({blueprint:t,errors:e})}}async validateBlueprint(e){var t;let i=JSON.stringify({blueprint:e,filter:this.filterNameValue}),n=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;const a=await fetch(this.updateStableIdUrlValue,{method:"PUT",body:i,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":n}}),r=await a.json();return a.ok?{stableId:r.filter_id}:{errors:r.errors}}}v.values={stableId:String,updateStableIdUrl:String,filterName:String},v.targets=[];class S extends l{initialize(){this.updateBlueprint=a((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){l.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:a}=this,r=e.target.dataset;a.updateInput(n,{[i=i||r.inputKey||"value"]:t=t||e.target.value},r.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let a=JSON.stringify({blueprint:e,filter:t}),r=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:a,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,a=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,a),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}S.values={criterionId:Number,stableId:String},require("daterangepicker/daterangepicker.css");class I extends e{connect(){this.initPluginInstance()}disconnect(){this.teardownPluginInstance()}clearDate(e){e.preventDefault(),r(this.fieldTarget).val("")}applyDateToField(e,t){const i=this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY";r(this.fieldTarget).val(t.startDate.format(i)),r(this.fieldTarget).trigger("change",t)}showTimeZoneButtons(e){e.preventDefault(),r(this.currentTimeZoneWrapperTarget).toggleClass("hidden"),r(this.timeZoneButtonsTarget).toggleClass("hidden")}showTimeZoneSelectWrapper(e){e.preventDefault(),r(this.timeZoneButtonsTarget).toggleClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&r(this.timeZoneSelectWrapperTarget).toggleClass("hidden")}resetTimeZoneUI(e){e&&e.preventDefault(),r(this.currentTimeZoneWrapperTarget).removeClass("hidden"),r(this.timeZoneButtonsTarget).addClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&r(this.timeZoneSelectWrapperTarget).addClass("hidden")}setTimeZone(e){e.preventDefault();const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target.dataset;r(this.timeZoneFieldTarget).val(i),r(t).text(i),r(".time-zone-button").removeClass("button").addClass("button-alternative"),r(e.target).removeClass("button-alternative").addClass("button"),this.resetTimeZoneUI()}initPluginInstance(){r(this.fieldTarget).daterangepicker({singleDatePicker:!0,timePicker:this.includeTimeValue,timePickerIncrement:5,autoUpdateInput:!1,minDate:!!this.futureOnlyValue&&new Date,locale:{cancelLabel:this.cancelButtonLabelValue,applyLabel:this.applyButtonLabelValue,format:this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY"},parentEl:r(this.element),drops:this.dropsValue?this.dropsValue:"down"}),r(this.fieldTarget).on("apply.daterangepicker",this.applyDateToField.bind(this)),r(this.fieldTarget).on("cancel.daterangepicker",this.clearDate.bind(this)),this.pluginMainEl=this.fieldTarget,this.plugin=r(this.pluginMainEl).data("daterangepicker"),this.includeTimeValue&&this.hasTimeZoneSelectWrapperTarget&&(this.timeZoneSelect=this.timeZoneSelectWrapperTarget.querySelector("select.select2"),r(this.timeZoneSelect).select2({width:"style"}),r(this.timeZoneSelect).on("change.select2",e=>{const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target;r(this.timeZoneFieldTarget).val(i),r(t).text(i);const n=r(".selected-option-time-zone-button");this.defaultTimeZonesValue.includes(i)?(r(".time-zone-button").removeClass("button").addClass("button-alternative"),n.addClass("hidden").attr("hidden",!0),r(`a[data-value="${i}"`).removeClass("button-alternative").addClass("button")):(r(".time-zone-button").removeClass("button").addClass("button-alternative"),n.text(i),n.attr("data-value",i).removeAttr("hidden"),n.removeClass(["hidden","button-alternative"]).addClass("button")),this.resetTimeZoneUI()}))}teardownPluginInstance(){void 0!==this.plugin&&(r(this.pluginMainEl).off("apply.daterangepicker"),r(this.pluginMainEl).off("cancel.daterangepicker"),this.plugin.remove(),this.includeTimeValue&&r(this.timeZoneSelect).select2("destroy"))}}I.targets=["field","clearButton","currentTimeZoneWrapper","timeZoneButtons","timeZoneSelectWrapper","timeZoneField"],I.values={includeTime:Boolean,defaultTimeZones:Array,futureOnly:Boolean,drops:String,cancelButtonLabel:{type:String,default:"Cancel"},applyButtonLabel:{type:String,default:"Apply"}};const T=[[o,"refine/add-controller.js"],[d,"refine/defaults-controller.js"],[u,"refine/delete-controller.js"],[l,"refine/form-controller.js"],[h,"refine/search-filter-controller.js"],[f,"refine/state-controller.js"],[g,"refine/stored-filter-controller.js"],[v,"refine/stabilize-filter-controller.js"],[S,"refine/update-controller.js"],[I,"refine/date-controller.js"]].map(function(e){const t=e[0];return{identifier:s(e[1]),controllerConstructor:t}});export{o as AddController,I as DateController,d as DefaultsController,u as DeleteController,l as FormController,h as SearchFilterController,v as StabilizeFilterController,f as StateController,g as StoredFilterController,S as UpdateController,T as controllerDefinitions}; | ||
//# sourceMappingURL=refine-stimulus.modern.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@hotwired/stimulus"),require("@rails/request.js"),require("jquery-events-to-dom-events"),require("lodash")):"function"==typeof define&&define.amd?define(["exports","@hotwired/stimulus","@rails/request.js","jquery-events-to-dom-events","lodash"],t):t((e||self).refineStimulus={},e.Stimulus,e.request_js,e.jqueryEventsToDomEvents,e.lodash)}(this,function(e,t,i,n,r){function s(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class l extends t.Controller{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class a extends l{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}a.values={previousCriterionId:Number};class o extends t.Controller{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}o.values={criterionId:Number,input:Object};class d extends l{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}d.values={criterionId:Number};class u extends t.Controller{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const e=this,{blueprint:t}=e.stateController;return Promise.resolve(e.stabilizeFilterController.validateBlueprint(t)).then(function(i){i.stableId?e.redirectToStableId(i.stableId):e.fetchAndRenderInvalidFilter(t)})}catch(e){return Promise.reject(e)}}addHiddenInput(e){let{name:t,value:i}=e;const n=document.createElement("input");n.type="hidden",n.name=t,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(t)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(e){try{const t=this,n=new i.FetchRequest("POST",t.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:t.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:t.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(e){return Promise.reject(e)}}}u.values={submitUrl:String},u.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const c=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},h=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},p=(e,t,i)=>{var n;const r=null==i?void 0:i.component,s=(null==i?void 0:i.meta)||{clauses:[],options:{}},l=(null==i?void 0:i.refinements)||[],{clauses:a,options:o}=s;let d={clause:null==(n=a[0])?void 0:n.id,selected:"option-condition"===r?[o[0].id]:void 0};return l.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:r,options:s}=i;d[e.id]={clause:r[0].id,selected:"option-condition"===n?[null==(t=s[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class b extends t.Controller{connect(){this.element.refineStateController=this,this.changeDelegate=n.delegate("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,h(this.element,this.blueprint)}disconnect(){n.abnegate("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(p(t.id,1,t)),h(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var r;t.splice(e+1,0,{depth:r=void 0===r?1:r,type:"conjunction",word:"and"},p(n.id,1,n)),h(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],r=i&&"or"===i.word,s=n&&"or"===n.word||!n,l=r||!i,a=l&&s;i||n?t.splice(a&&r?e-1:a&&!i||l&&!s?e:e-1,2):this.blueprint=[],h(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(p));this.blueprint[e]=p(t,n.depth,i),h(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,r=n[e],s=(i=i||"input").split(", ");s.length>1?r[s[0]][s[1]]={...r[s[0]][s[1]],...t}:r[i]={...r[i],...t},h(this.element,this.blueprint)}}b.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},b.targets=["loading"];class m extends t.Controller{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}m.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],m.values={id:Number,stableId:String,filterName:String};class f extends t.Controller{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(e){try{const t=this;(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});window.dispatchEvent(t)})(t.blueprint);const i=e.detail.blueprint;return Promise.resolve(t.validateBlueprint(i)).then(function(e){if(e.stableId)t.stableIdValue=e.stableId,c(t.element,t.stableIdValue,t.filterNameValue),c(window,t.stableIdValue,t.filterNameValue);else{const{errors:t}=e;(e=>{let{blueprint:t,errors:i}=e;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:t})}})}catch(e){return Promise.reject(e)}}validateBlueprint(e){try{var t;const i=this;let n=JSON.stringify({blueprint:e,filter:i.filterNameValue}),r=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r}})).then(function(e){return Promise.resolve(e.json()).then(function(t){return e.ok?{stableId:t.filter_id}:{errors:t.errors}})})}catch(e){return Promise.reject(e)}}}f.values={stableId:String,updateStableIdUrl:String,filterName:String},f.targets=[];class v extends l{initialize(){this.updateBlueprint=r.debounce((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){l.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:r}=this,s=e.target.dataset;r.updateInput(n,{[i=i||s.inputKey||"value"]:t=t||e.target.value},s.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let r=JSON.stringify({blueprint:e,filter:t}),s=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:r,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":s},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,r=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,r),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}v.values={criterionId:Number,stableId:String};const g=[[a,"refine/add-controller.js"],[o,"refine/defaults-controller.js"],[d,"refine/delete-controller.js"],[l,"refine/form-controller.js"],[u,"refine/search-filter-controller.js"],[b,"refine/state-controller.js"],[m,"refine/stored-filter-controller.js"],[f,"refine/stabilize-filter-controller.js"],[v,"refine/update-controller.js"]].map(function(e){const t=e[0];return{identifier:s(e[1]),controllerConstructor:t}});e.AddController=a,e.DefaultsController=o,e.DeleteController=d,e.FormController=l,e.SearchFilterController=u,e.StabilizeFilterController=f,e.StateController=b,e.StoredFilterController=m,e.UpdateController=v,e.controllerDefinitions=g}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@hotwired/stimulus"),require("@rails/request.js"),require("jquery-events-to-dom-events"),require("lodash"),require("jquery"),require("daterangepicker")):"function"==typeof define&&define.amd?define(["exports","@hotwired/stimulus","@rails/request.js","jquery-events-to-dom-events","lodash","jquery","daterangepicker"],t):t((e||self).refineStimulus={},e.Stimulus,e.request_js,e.jqueryEventsToDomEvents,e.lodash,e.$$1)}(this,function(e,t,i,n,a,r){function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=l(r);function o(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}class d extends t.Controller{connect(){this.state=this.getStateController(),this.blueprintInput=this.addHiddenInput("blueprint"),this.addHiddenInput("filter",this.state.filterName),this.addHiddenInput("id_suffix",this.state.idSuffix),this.finishUpdate()}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}addHiddenInput(e,t){const i=document.createElement("input");return i.type="hidden",i.name=e,i.value=t||"",this.element.appendChild(i),i}finishUpdate(){this.state.finishUpdate()}startUpdate(){this.blueprintInput.value=JSON.stringify(this.state.blueprint),this.state.startUpdate()}submitForm(){this.startUpdate(),this.element.requestSubmit()}}class u extends d{criterion(){this.state.addCriterion(this.previousCriterionIdValue),this.startUpdate()}group(){this.state.addGroup(),this.startUpdate()}}u.values={previousCriterionId:Number};class c extends t.Controller{connect(){this.state=this.getStateController(),this.state.updateInput(this.criterionIdValue,this.inputValue)}getStateController(){let e=this.element;for(;e!==document.body;){const t=this.application.getControllerForElementAndIdentifier(e,"refine--state");if(t)return t;e=e.parentNode}return null}}c.values={criterionId:Number,input:Object};class h extends d{criterion(){const{state:e,criterionIdValue:t}=this;e.deleteCriterion(t),this.startUpdate()}}h.values={criterionId:Number};class p extends t.Controller{connect(){const e=new URLSearchParams(window.location.search);this.existingParams=e,this.existingParams.delete("stable_id")}search(e){e.preventDefault(),this.submitFilter(),document.activeElement.blur()}submitFilter(){try{const e=this,{blueprint:t}=e.stateController;return Promise.resolve(e.stabilizeFilterController.validateBlueprint(t)).then(function(i){i.stableId?e.redirectToStableId(i.stableId):e.fetchAndRenderInvalidFilter(t)})}catch(e){return Promise.reject(e)}}addHiddenInput(e){let{name:t,value:i}=e;const n=document.createElement("input");n.type="hidden",n.name=t,n.value=i,this.submissionFormTarget.appendChild(n)}get stateController(){return this.element.querySelector('[data-controller~="refine--state"]').refineStateController}get stabilizeFilterController(){return this.element.stabilizeFilterController}redirectToStableId(e){const t=new URLSearchParams;e&&t.append("stable_id",e);const i=new URLSearchParams({...Object.fromEntries(this.existingParams),...Object.fromEntries(t)}).toString(),n=window.location.pathname+"?"+i;history.pushState({},document.title,n),window.location.reload()}fetchAndRenderInvalidFilter(e){try{const t=this,n=new i.FetchRequest("POST",t.submitUrlValue,{responseKind:"turbo-stream",body:JSON.stringify({filter:t.stateController.filterName,blueprint:JSON.stringify(e),id_suffix:t.stateController.idSuffix})});return Promise.resolve(n.perform()).then(function(){})}catch(e){return Promise.reject(e)}}}p.values={submitUrl:String},p.targets=[],function(){if("function"==typeof window.CustomEvent)return!1;function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}e.prototype=window.Event.prototype,window.CustomEvent=e}();const m=(e,t,i)=>{const n=new CustomEvent("filter-stabilized",{bubbles:!0,cancelable:!0,detail:{stableId:t,filterName:i}});e.dispatchEvent(n)},f=(e,t)=>{const i=new CustomEvent("blueprint-updated",{bubbles:!0,cancelable:!0,detail:{blueprint:t}});e.dispatchEvent(i)},b=(e,t,i)=>{var n;const a=null==i?void 0:i.component,r=(null==i?void 0:i.meta)||{clauses:[],options:{}},l=(null==i?void 0:i.refinements)||[],{clauses:s,options:o}=r;let d={clause:null==(n=s[0])?void 0:n.id,selected:"option-condition"===a?[o[0].id]:void 0};return l.forEach(e=>{var t;const{meta:i,component:n}=e,{clauses:a,options:r}=i;d[e.id]={clause:a[0].id,selected:"option-condition"===n?[null==(t=r[0])?void 0:t.id]:void 0}}),{depth:t,type:"criterion",condition_id:e,input:d}};class g extends t.Controller{connect(){this.element.refineStateController=this,this.changeDelegate=n.delegate("change",["event","picker"]),this.blueprint=this.blueprintValue,this.conditions=this.conditionsValue,this.filterName=this.classNameValue,this.idSuffix=this.idSuffixValue,this.stableId=this.stableIdValue,this.conditionsLookup=this.conditions.reduce((e,t)=>(e[t.id]=t,e),{}),this.loadingTimeout=null,f(this.element,this.blueprint)}disconnect(){n.abnegate("change",this.changeDelegate)}startUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTimeout=window.setTimeout(()=>{document.activeElement.blur(),this.loadingTarget.classList.remove("hidden")},1e3)}finishUpdate(){this.loadingTimeout&&window.clearTimeout(this.loadingTimeout),this.loadingTarget.classList.add("hidden")}conditionConfigFor(e){return this.conditionsLookup[e]}updateStableId(e){e!==this.stableId&&(this.stableId=e)}addGroup(){const{conditions:e}=this,t=e[0];var i;this.blueprint.length>0&&this.blueprint.push({depth:i=void 0===i?0:i,type:"conjunction",word:"or"}),this.blueprint.push(b(t.id,1,t)),f(this.element,this.blueprint)}addCriterion(e){const{blueprint:t,conditions:i}=this,n=i[0];var a;t.splice(e+1,0,{depth:a=void 0===a?1:a,type:"conjunction",word:"and"},b(n.id,1,n)),f(this.element,this.blueprint)}deleteCriterion(e){const{blueprint:t}=this,i=t[e-1],n=t[e+1],a=i&&"or"===i.word,r=n&&"or"===n.word||!n,l=a||!i,s=l&&r;i||n?t.splice(s&&a?e-1:s&&!i||l&&!r?e:e-1,2):this.blueprint=[],f(this.element,this.blueprint)}replaceCriterion(e,t,i){const n=this.blueprint[e];if("criterion"!==n.type)throw new Error("You can't call updateConditionId on a non-criterion type. Trying to update "+JSON.stringify(b));this.blueprint[e]=b(t,n.depth,i),f(this.element,this.blueprint)}updateInput(e,t,i){const{blueprint:n}=this,a=n[e],r=(i=i||"input").split(", ");r.length>1?a[r[0]][r[1]]={...a[r[0]][r[1]],...t}:a[i]={...a[i],...t},f(this.element,this.blueprint)}}g.values={blueprint:Array,conditions:Array,className:String,stableId:String,idSuffix:String},g.targets=["loading"];class v extends t.Controller{connect(){this.idValue&&(e=>{const t=new CustomEvent("filter-stored",{bubbles:!0,cancelable:!0,detail:{storedFilterId:this.idValue}});window.dispatchEvent(t)})()}updateStableIdField(e){if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasStableIdFieldTarget){const{detail:t}=e,{stableId:i}=t;this.stableIdFieldTarget.value=i}}activateSaveLink(e){const{detail:t}=e,{stableId:i}=t;if(e.detail.filterName!=this.filterNameValue)return null;if(this.hasEnabledSaveLinkTarget&&this.hasDisabledSaveLinkTarget){const e=new URL(this.enabledSaveLinkTarget.href);e.searchParams.set("stable_id",i),this.enabledSaveLinkTarget.setAttribute("href",e),this.disabledSaveLinkTarget.classList.add("hidden"),this.enabledSaveLinkTarget.classList.remove("hidden")}}}v.targets=["enabledSaveLink","disabledSaveLink","stableIdField"],v.values={id:Number,stableId:String,filterName:String};class S extends t.Controller{connect(){this.element.stabilizeFilterController=this,this.stableIdValue=new URLSearchParams(window.location.search).get("stable_id")}updateStableId(e){try{const t=this;(e=>{const t=new CustomEvent("filter-unstable",{bubbles:!0,cancelable:!0,detail:{blueprint:e}});window.dispatchEvent(t)})(t.blueprint);const i=e.detail.blueprint;return Promise.resolve(t.validateBlueprint(i)).then(function(e){if(e.stableId)t.stableIdValue=e.stableId,m(t.element,t.stableIdValue,t.filterNameValue),m(window,t.stableIdValue,t.filterNameValue);else{const{errors:t}=e;(e=>{let{blueprint:t,errors:i}=e;const n=new CustomEvent("filter-invalid",{bubbles:!0,cancelable:!0,detail:{blueprint:t,errors:i}});window.dispatchEvent(n)})({blueprint:i,errors:t})}})}catch(e){return Promise.reject(e)}}validateBlueprint(e){try{var t;const i=this;let n=JSON.stringify({blueprint:e,filter:i.filterNameValue}),a=null==(t=document.querySelector("meta[name='csrf-token']"))?void 0:t.content;return Promise.resolve(fetch(i.updateStableIdUrlValue,{method:"PUT",body:n,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":a}})).then(function(e){return Promise.resolve(e.json()).then(function(t){return e.ok?{stableId:t.filter_id}:{errors:t.errors}})})}catch(e){return Promise.reject(e)}}}S.values={stableId:String,updateStableIdUrl:String,filterName:String},S.targets=[];class C extends d{initialize(){this.updateBlueprint=a.debounce((e,t,i)=>{this.value(e,t,i),this.createStableId(this.state.blueprint,this.state.filterName)},500)}connect(){d.prototype.connect.apply(this),this.state.updateStableId(this.stableIdValue)}refinedFilter(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{id:e.target.value},e.target.dataset.inputId),this.submitForm()}clause(e){const{criterionIdValue:t,state:i}=this;i.updateInput(t,{clause:e.target.value},e.target.dataset.inputId),this.submitForm()}selected(e){const{target:t}=e,i=Array.prototype.slice.call(t.options).filter(e=>e.selected).map(e=>e.value);this.value(e,i,"selected"),this.createStableId(this.state.blueprint,this.state.filterName)}value(e,t,i){const{criterionIdValue:n,state:a}=this,r=e.target.dataset;a.updateInput(n,{[i=i||r.inputKey||"value"]:t=t||e.target.value},r.inputId)}date(e){const{picker:t}=e.detail,i=t.startDate.format("YYYY-MM-DD");this.value(e,i),this.submitForm()}createStableId(e,t){var i;const{state:n}=this;let a=JSON.stringify({blueprint:e,filter:t}),r=null==(i=document.querySelector("meta[name='csrf-token']"))?void 0:i.content;$.ajax({type:"PUT",url:"/hammerstone/update_stable_id",data:a,headers:{accept:"application/json","content-type":"application/json","X-CSRF-Token":r},success:function(e){n.updateStableId(e.filter_id)}})}condition(e){const{criterionIdValue:t,state:i}=this,n=e.target.value,a=this.state.conditionConfigFor(n);i.replaceCriterion(t,n,a),this.submitForm()}cancelEnter(e){"Enter"===e.code&&(e.preventDefault(),e.stopPropagation())}}C.values={criterionId:Number,stableId:String},require("daterangepicker/daterangepicker.css");class I extends t.Controller{connect(){this.initPluginInstance()}disconnect(){this.teardownPluginInstance()}clearDate(e){e.preventDefault(),s.default(this.fieldTarget).val("")}applyDateToField(e,t){const i=this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY";s.default(this.fieldTarget).val(t.startDate.format(i)),s.default(this.fieldTarget).trigger("change",t)}showTimeZoneButtons(e){e.preventDefault(),s.default(this.currentTimeZoneWrapperTarget).toggleClass("hidden"),s.default(this.timeZoneButtonsTarget).toggleClass("hidden")}showTimeZoneSelectWrapper(e){e.preventDefault(),s.default(this.timeZoneButtonsTarget).toggleClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&s.default(this.timeZoneSelectWrapperTarget).toggleClass("hidden")}resetTimeZoneUI(e){e&&e.preventDefault(),s.default(this.currentTimeZoneWrapperTarget).removeClass("hidden"),s.default(this.timeZoneButtonsTarget).addClass("hidden"),this.hasTimeZoneSelectWrapperTarget&&s.default(this.timeZoneSelectWrapperTarget).addClass("hidden")}setTimeZone(e){e.preventDefault();const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target.dataset;s.default(this.timeZoneFieldTarget).val(i),s.default(t).text(i),s.default(".time-zone-button").removeClass("button").addClass("button-alternative"),s.default(e.target).removeClass("button-alternative").addClass("button"),this.resetTimeZoneUI()}initPluginInstance(){s.default(this.fieldTarget).daterangepicker({singleDatePicker:!0,timePicker:this.includeTimeValue,timePickerIncrement:5,autoUpdateInput:!1,minDate:!!this.futureOnlyValue&&new Date,locale:{cancelLabel:this.cancelButtonLabelValue,applyLabel:this.applyButtonLabelValue,format:this.includeTimeValue?"MM/DD/YYYY h:mm A":"MM/DD/YYYY"},parentEl:s.default(this.element),drops:this.dropsValue?this.dropsValue:"down"}),s.default(this.fieldTarget).on("apply.daterangepicker",this.applyDateToField.bind(this)),s.default(this.fieldTarget).on("cancel.daterangepicker",this.clearDate.bind(this)),this.pluginMainEl=this.fieldTarget,this.plugin=s.default(this.pluginMainEl).data("daterangepicker"),this.includeTimeValue&&this.hasTimeZoneSelectWrapperTarget&&(this.timeZoneSelect=this.timeZoneSelectWrapperTarget.querySelector("select.select2"),s.default(this.timeZoneSelect).select2({width:"style"}),s.default(this.timeZoneSelect).on("change.select2",e=>{const t=this.currentTimeZoneWrapperTarget.querySelector("a"),{value:i}=e.target;s.default(this.timeZoneFieldTarget).val(i),s.default(t).text(i);const n=s.default(".selected-option-time-zone-button");this.defaultTimeZonesValue.includes(i)?(s.default(".time-zone-button").removeClass("button").addClass("button-alternative"),n.addClass("hidden").attr("hidden",!0),s.default('a[data-value="'+i+'"').removeClass("button-alternative").addClass("button")):(s.default(".time-zone-button").removeClass("button").addClass("button-alternative"),n.text(i),n.attr("data-value",i).removeAttr("hidden"),n.removeClass(["hidden","button-alternative"]).addClass("button")),this.resetTimeZoneUI()}))}teardownPluginInstance(){void 0!==this.plugin&&(s.default(this.pluginMainEl).off("apply.daterangepicker"),s.default(this.pluginMainEl).off("cancel.daterangepicker"),this.plugin.remove(),this.includeTimeValue&&s.default(this.timeZoneSelect).select2("destroy"))}}I.targets=["field","clearButton","currentTimeZoneWrapper","timeZoneButtons","timeZoneSelectWrapper","timeZoneField"],I.values={includeTime:Boolean,defaultTimeZones:Array,futureOnly:Boolean,drops:String,cancelButtonLabel:{type:String,default:"Cancel"},applyButtonLabel:{type:String,default:"Apply"}};const T=[[u,"refine/add-controller.js"],[c,"refine/defaults-controller.js"],[h,"refine/delete-controller.js"],[d,"refine/form-controller.js"],[p,"refine/search-filter-controller.js"],[g,"refine/state-controller.js"],[v,"refine/stored-filter-controller.js"],[S,"refine/stabilize-filter-controller.js"],[C,"refine/update-controller.js"],[I,"refine/date-controller.js"]].map(function(e){const t=e[0];return{identifier:o(e[1]),controllerConstructor:t}});e.AddController=u,e.DateController=I,e.DefaultsController=c,e.DeleteController=h,e.FormController=d,e.SearchFilterController=p,e.StabilizeFilterController=S,e.StateController=g,e.StoredFilterController=v,e.UpdateController=C,e.controllerDefinitions=T}); | ||
//# sourceMappingURL=refine-stimulus.umd.js.map |
@@ -12,2 +12,3 @@ import { identifierForContextKey } from "@hotwired/stimulus-webpack-helpers" | ||
import UpdateController from './refine/update-controller' | ||
import DateController from './refine/date-controller' | ||
@@ -23,3 +24,4 @@ export const controllerDefinitions = [ | ||
[StabilizeFilterController, 'refine/stabilize-filter-controller.js'], | ||
[UpdateController, 'refine/update-controller.js'] | ||
[UpdateController, 'refine/update-controller.js'], | ||
[DateController, 'refine/date-controller.js'] | ||
].map(function(d) { | ||
@@ -43,3 +45,4 @@ const key = d[1] | ||
StabilizeFilterController, | ||
UpdateController | ||
UpdateController, | ||
DateController | ||
} |
@@ -0,1 +1,6 @@ | ||
### 2.2.3 (not yet released) | ||
* Add date picker to the gem. Note - this will override the `fields/date_controller` currently being used in client. Styles should already be imported via client, confirm before merge. | ||
* bug-fix | ||
* Uncomment out Options Conditions test and fix `set` `not-set` conditions | ||
### 2.2.2 2022-09-07 | ||
@@ -2,0 +7,0 @@ * bug-fix |
{ | ||
"name": "@hammerstone/refine-stimulus", | ||
"version": "2.2.2", | ||
"version": "2.2.3", | ||
"description": "Refine is a flexible query builder for your apps. It lets your users filter down to exactly what they're looking for. Completely configured on the backend.", | ||
@@ -60,2 +60,3 @@ "browserslist": [ | ||
"@rails/request.js": "^0.0.6", | ||
"daterangepicker": "^3.1.0", | ||
"jquery-events-to-dom-events": "^1.1.0", | ||
@@ -62,0 +63,0 @@ "lodash": "^4.0.8" |
242
README.md
@@ -1,2 +0,3 @@ | ||
## Adding Refine to a non Bullet Train application | ||
## How to integrate the refine filter | ||
1. Add the gem | ||
@@ -16,10 +17,38 @@ | ||
3. `bundle` `yarn` | ||
3. `bundle` | ||
4. In the controller you'd like to filter on, add the `apply_filter` method. For this example we'll use Contacts. | ||
`@refine_filter = apply_filter(ContactsFilter)` | ||
4. `yarn` | ||
5. Create a `app/filters/contacts_filter.rb` with the following: | ||
5. Import the Stimulus Controllers in your application. | ||
Typically this is in `app/javascript/controllers/index.js` | ||
```javascript | ||
import { controllerDefinitions as refineControllers } from "@hammerstone/refine-stimulus" | ||
application.load(refineControllers) | ||
``` | ||
Depending on how you import Stimulus Controllers and define `application` it may be `Stimulus.load(refineControllers)` | ||
## Troubleshooting Stimulus Controllers | ||
To make sure the Stimulus controllers are loaded properly, add `window.Stimulus=application` to `controllers/index.js` | ||
Then in the console inspect the stimulus object: | ||
```bash | ||
Stimulus.router.modulesByIdentifier | ||
``` | ||
You should see the `refine--....` controllers listed | ||
6. Add jquery (necessary for date picker) | ||
`yarn add jquery` | ||
``` | ||
import jquery from 'jquery' | ||
window.jQuery = jquery | ||
window.$ = jquery | ||
``` | ||
7. Implement a Filter class in `app/filters` that inherits from `Hammerstone::Refine::Filter`. Use this class to define the conditions that can be filtered. | ||
Example (Contacts Filter on a Contact Model) | ||
```ruby | ||
# app/filters/contacts_filter.rb | ||
class ContactsFilter < Hammerstone::Refine::Filter | ||
@@ -42,3 +71,3 @@ @@default_stabilizer = Hammerstone::Refine::Stabilizers::UrlEncodedStabilizer | ||
[ | ||
Hammerstone::Refine::Conditions::TextCondition.new("first_name"), | ||
Hammerstone::Refine::Conditions::TextCondition.new("name"), | ||
Hammerstone::Refine::Conditions::DateCondition.new("created_at"), | ||
@@ -52,105 +81,167 @@ Hammerstone::Refine::Conditions::DateCondition.new("updated_at"), | ||
6. In your application controller, `include Hammerstone::FilterApplicationController` | ||
8. In your application controller, `include Hammerstone::FilterApplicationController` which is a helper class to get you up and running quickly. You can remove it and use your own `apply_filter` method if you want. | ||
7. Render the filter partial wherever you want! | ||
## Troubleshooting: | ||
If you see this error: | ||
``` | ||
<div class="flex flex-col"> | ||
<%# Include the this line if you'd like to dump the sql for testing %> | ||
<%#= @refine_filter&.get_query&.to_sql %> | ||
<%= render partial: 'hammerstone/filter_builder_dropdown' %> | ||
</div> | ||
NameError (uninitialized constant ApplicationController::Hammerstone | ||
web | | ||
web | include Hammerstone::FilterApplicationController | ||
``` | ||
8. Set the filter stabilized ENV var or credential. If using rails credentials: | ||
`EDITOR="subl --wait" bin/rails credentials:edit --environment development` and set `NAMESPACE_REFINE_STABILIZERS: 1` | ||
If using .env, application.yml or another gem set `NAMESPACE_REFINE_STABILIZERS=1` | ||
Please restart your server! | ||
9. Import the Stimulus Controllers. | ||
``` | ||
// import { Application } from "stimulus" | ||
import { controllerDefinitions as refineControllers } from "@hammerstone/refine-stimulus" | ||
// window.Stimulus = Application.start() | ||
Stimulus.load(refineControllers) | ||
``` | ||
9. In the controller you'd like to filter on, add the `apply_filter` method. For this example we'll use Contacts model and filter. | ||
`@refine_filter = apply_filter(ContactsFilter)` | ||
10. Add jquery (necessary for date picker) | ||
`yarn add jquery` | ||
This is a helper method you can inspect in `Hammerstone::FilterApplicationController`. You probably *do not* want to use this method but want to implement your own. It will return `@refine_filter` which is generated from the stable_id. The `stable_id` comes in from the params when the form is submitted or the URL is directly changed. | ||
10. Set the filter stabilized ENV var or credential. | ||
If using rails credentials: EDITOR="subl --wait" bin/rails credentials:edit --environment development and set NAMESPACE_REFINE_STABILIZERS: 1 | ||
If using .env, application.yml or another gem set NAMESPACE_REFINE_STABILIZERS=1 | ||
11. Add the following to your index view to render a button that activates the filter: | ||
``` | ||
import jquery from 'jquery' | ||
window.jQuery = jquery | ||
window.$ = jquery | ||
<%= render partial: 'hammerstone/filter_builder_dropdown' %> | ||
``` | ||
### Refine::Rails How to Install - BT and legacy | ||
Short description and motivation. | ||
12. Add the `reveal` controller to your application if using the `filter_builder_dropdown` partial | ||
`yarn add stimulus-reveal` | ||
## Installation (if using BT see BulletTrain installation below) | ||
Add this line to your application's Gemfile: | ||
```javascript | ||
//index.js | ||
import RevealController from 'stimulus-reveal' | ||
```ruby | ||
gem "refine-rails" | ||
application.register('reveal', RevealController) | ||
``` | ||
And then execute: | ||
```bash | ||
$ bundle | ||
13. If the gems tailwind styles are being purged with JIT you can add the gem to `tmp/gems` and add this to your tailwing config. | ||
``` tailwind.config.js | ||
'./tmp/gems/*/app/views/**/*.html.erb', | ||
'./tmp/gems/*/app/helpers/**/*.rb', | ||
'./tmp/gems/*/app/assets/stylesheets/**/*.css', | ||
'./tmp/gems/*/app/javascript/**/*.js', | ||
``` | ||
Or install it yourself as: | ||
```bash | ||
$ gem install refine-rails | ||
Run the following rake task: | ||
``` | ||
task :add_temp_gems do | ||
target = `bundle show refine-rails`.chomp | ||
if target.present? | ||
puts "Linking refine-rails to '#{target}'." | ||
`ln -s #{target} tmp/gems/refine-rails` | ||
end | ||
end | ||
``` | ||
Installing the JavaScript package: | ||
Don't forget to restart the server! | ||
```bash | ||
$ yarn add @hammerstone/refine-stimulus | ||
14. Add external styles - currently themify icons (can be overriden - the trash can icon is located in `_criterion.html.erb`) and `daterangepicker` | ||
A quick way to load them is in the `head` section. Also available as an npm package. | ||
``` | ||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" /> | ||
<link rel="stylesheet" href="https://unpkg.com/@icon/themify-icons/themify-icons.css"> | ||
``` | ||
Also, make sure that your project uses `jquery` and binds it as `window.$`. Required for catching events dispatched by `select2` dropdowns. | ||
## How it works | ||
Also note that there's currently a bug with esbuild and stimulus 3.0 compatibility. | ||
The query builder component emits javascript events which give you information about the state of the filter. The filter emits the following events: | ||
- blueprint-updated | ||
- filter-unstable | ||
- filter-stabilized | ||
- filter-invalid | ||
- filter-stored | ||
### Importing and Registering the Stimulus Controllers | ||
#### blueprint-updated | ||
This event is emitted when user input has resulted in a change to the blueprint. Refine uses this event internally and you can use it in your own code to listen for changes and get the latest state of the form. | ||
Where you normally import your Stimulus controllers, add the following lines: | ||
event.detail includes the following properties: | ||
- blueprint: a Javascript object detailing the user input to the filter form | ||
#### filter-unstable | ||
This event is emitted when the filter is validating and fetching a new URL-encoded stable ID from the server. This event signals that the current stable_id is out of date. The stable_id should not be used until a filter-stabilized event is emitted. | ||
When the round-trip to the server completes a filter-stabilized event is emitted if the filter is valid. If the filter is not valid a filter-invalid event will be emitted. | ||
event.detail includes the following properties: | ||
- blueprint: a Javascript object detailing the user input to the filter form | ||
#### filter-stabilized | ||
This event is emitted when the filter has been automatically URL encoded and completed the server side calls. At this point it is safe to use the stable_id. The stable_id will look something like `H4sIAPJsT2IAAzWNwQoDIQxE%252F2XOHrpX....` The stable_id allows the user to copy, share, refresh, or otherwise store the URL, but does not save it to the database. This stabilizer is a great way to allow users to not lose all of their progress without having to save every filter to the database. Note: All filters in the CF repo are automatically URL encode stabilized unless you have explicitly set it differently in your filter class. | ||
event.detail includes the following properties: | ||
- stableId: the URL encoded ID that can be used to reconstruct the filter. | ||
- filterName: the class name of the filter this ID is for defined in your ruby code | ||
#### filter-invalid | ||
This event is emitted when Refine has attempted to refresh the stable_id for the filter but was unable to do so because the user input is not valid. | ||
event.detail includes the following properties: | ||
- blueprint: a Javascript object detailing the user input to the filter form | ||
- errors: an array of error messages describing why the filter is not valid | ||
#### filter-stored: This event is emitted when the filter has been saved to the database (i.e. the user clicked "Save Filter"). | ||
event.detail includes the following properties | ||
storedFilterId: the primary key of the associated record in the hammerstone_refine_stored_filters_table | ||
## Forcing validations | ||
To force validations, make a POST request to /hammerstone/refine_blueprints with the following JSON payload: | ||
- filter: the ruby class name of the filter | ||
- blueprint: a JSON-stringifed version of the user-input blueprint | ||
- id_suffix: the string appended to DOM-ids used to uniquely identify this filter | ||
The server will respond with a JSON payload that either includes the URL-encoded stable_id (if valid) or a JSON payload or HTML markup that can be used to rerender the form including validation messages | ||
Example: | ||
```js | ||
// import { Application } from "stimulus" | ||
import { controllerDefinitions as refineControllers } from "@hammerstone/refine-stimulus" | ||
// window.Stimulus = Application.start() | ||
Stimulus.load(refineControllers) | ||
const response = await fetch('/hammerstone/refine_blueprints', { | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json', | ||
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']")?.content | ||
}, | ||
method: "POST", | ||
body: JSON.stringify({ | ||
filter: 'ContactsFilter', | ||
blueprint: JSON.stringify(blueprint), | ||
id_suffix: 'contacts' | ||
}) | ||
}) | ||
``` | ||
If loading in Bullet Train,the load command is | ||
`application.load(refineControllers)` and the file is `app/javascript/controllers/index.js` | ||
#### Fetching a stable_id from the server | ||
If you need to get a URL-encoded stable_id for a filter without relying on the filter-stabilized event, you can make a PUT request to /hammerstone/update_stable_id with the following JSON payload: | ||
- filter: the ruby class name of the filter | ||
- blueprint: JSON stringified version of the current blueprint | ||
To manually register (or extend or provide your own replacement for) each Stimulus controller: | ||
Example: | ||
```js | ||
// import { Application } from "stimulus" | ||
import { | ||
AddController, | ||
DefaultsController, | ||
DeleteController, | ||
FormController, | ||
StateController, | ||
StoredFilterController, | ||
UpdateController | ||
} from "@hammerstone/refine-stimulus" | ||
// window.Stimulus = Application.start() | ||
Stimulus.register('refine--add', AddController) | ||
Stimulus.register('refine--defaults', DefaultsController) | ||
Stimulus.register('refine--delete', DeleteController) | ||
Stimulus.register('refine--form', FormController) | ||
Stimulus.register('refine--state', StateController) | ||
Stimulus.register('refine--stored-filter', StoredFilterController) | ||
Stimulus.register('refine--update', UpdateController) | ||
const response = await fetch(this.updateStableIdUrlValue, { | ||
method: 'PUT', | ||
headers: { | ||
accept: 'application/json', | ||
'content-type': 'application/json', | ||
'X-CSRF-Token': token, | ||
}, | ||
body: JSON.stringify({ | ||
filter: 'ContactsFilter', | ||
blueprint: JSON.stringify(blueprint), | ||
}) | ||
}) | ||
``` | ||
If the filter is valid, the server responds 200 OK with the stable_id in the JSON response | ||
If the filter is not valid, the server responds 422 Unprocessable Entity with an errors array in the JSON response | ||
## Local JavaScript Development | ||
@@ -222,5 +313,4 @@ | ||
### TO FIX | ||
- Figure out how to handle `ApplicationFilter` class and if we want to ship with an option of sending in initial query | ||
- Add `stored_filter.rb` (only if using stored filters - best way for users?) | ||
### TODO | ||
- Documentation for stored filters | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
282620
24
1005
313
5
+ Addeddaterangepicker@^3.1.0
+ Addeddaterangepicker@3.1.0(transitive)
+ Addedjquery@3.7.1(transitive)
+ Addedmoment@2.30.1(transitive)