@donotdev/crud 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/CrudService.js +2 -2
  2. package/dist/CrudStore.js +1 -1
  3. package/dist/FieldRegistry.d.ts +6 -5
  4. package/dist/FieldRegistry.d.ts.map +1 -1
  5. package/dist/FieldRegistry.js +1 -1
  6. package/dist/adapters/FunctionsAdapter.js +1 -1
  7. package/dist/components/CrudButton.js +1 -1
  8. package/dist/components/CrudCard.d.ts +1 -1
  9. package/dist/components/CrudCard.d.ts.map +1 -1
  10. package/dist/components/CrudCard.js +1 -1
  11. package/dist/components/DateFilter.js +1 -1
  12. package/dist/components/DisplayFieldRenderer.d.ts.map +1 -1
  13. package/dist/components/DisplayFieldRenderer.js +1 -1
  14. package/dist/components/DisplayThumbnail.js +1 -1
  15. package/dist/components/EntityFilters.js +1 -1
  16. package/dist/components/FormFieldRenderer.js +1 -1
  17. package/dist/components/FormLayout.js +1 -1
  18. package/dist/components/controlled/complex/ControlledAddressField.js +1 -1
  19. package/dist/components/controlled/complex/ControlledDateField.js +1 -1
  20. package/dist/components/controlled/complex/ControlledFieldArrayField.js +1 -1
  21. package/dist/components/controlled/complex/ControlledGeoPointField.js +1 -1
  22. package/dist/components/controlled/complex/ControlledMapField.js +1 -1
  23. package/dist/components/controlled/complex/ControlledMultiInputField.js +1 -1
  24. package/dist/components/controlled/complex/ControlledRichTextField.js +1 -1
  25. package/dist/components/controlled/complex/ControlledTimestampField.js +1 -1
  26. package/dist/components/controlled/complex/index.js +1 -1
  27. package/dist/components/controlled/file/ControlledDocumentField.js +1 -1
  28. package/dist/components/controlled/file/ControlledFileField.js +1 -1
  29. package/dist/components/controlled/file/ControlledImageField.js +1 -1
  30. package/dist/components/controlled/file/ControlledMultiDocumentField.js +1 -1
  31. package/dist/components/controlled/file/ControlledMultiFileField.js +1 -1
  32. package/dist/components/controlled/file/ControlledMultiImageField.js +1 -1
  33. package/dist/components/controlled/file/index.js +1 -1
  34. package/dist/components/controlled/index.js +1 -1
  35. package/dist/components/controlled/input/ControlledCheckboxField.js +1 -1
  36. package/dist/components/controlled/input/ControlledCurrencyField.js +1 -1
  37. package/dist/components/controlled/input/ControlledDurationField.js +1 -1
  38. package/dist/components/controlled/input/ControlledGdprConsentField.js +1 -1
  39. package/dist/components/controlled/input/ControlledNumberField.js +1 -1
  40. package/dist/components/controlled/input/ControlledPasswordField.js +1 -1
  41. package/dist/components/controlled/input/ControlledPhoneField.js +1 -1
  42. package/dist/components/controlled/input/ControlledPriceField.js +1 -1
  43. package/dist/components/controlled/input/ControlledRangeField.js +1 -1
  44. package/dist/components/controlled/input/ControlledRatingField.js +1 -1
  45. package/dist/components/controlled/input/ControlledSwitchField.js +1 -1
  46. package/dist/components/controlled/input/ControlledTextField.js +1 -1
  47. package/dist/components/controlled/input/ControlledTextareaField.js +1 -1
  48. package/dist/components/controlled/input/index.js +1 -1
  49. package/dist/components/controlled/select/ControlledComboboxField.js +1 -1
  50. package/dist/components/controlled/select/ControlledDropdownField.js +1 -1
  51. package/dist/components/controlled/select/ControlledMultiDropdownField.js +1 -1
  52. package/dist/components/controlled/select/ControlledRadioField.js +1 -1
  53. package/dist/components/controlled/select/ControlledReferenceField.js +1 -1
  54. package/dist/components/controlled/select/ControlledYearField.js +1 -1
  55. package/dist/components/controlled/select/index.js +1 -1
  56. package/dist/components/controlled/types.js +1 -1
  57. package/dist/components/fields/display/AvatarFieldDisplay.js +1 -1
  58. package/dist/components/fields/display/BadgeFieldDisplay.js +1 -1
  59. package/dist/components/fields/display/ButtonFieldDisplay.js +1 -1
  60. package/dist/components/fields/display/CheckboxFieldDisplay.js +1 -1
  61. package/dist/components/fields/display/DateFieldDisplay.js +1 -1
  62. package/dist/components/fields/display/DropdownDisplay.js +1 -1
  63. package/dist/components/fields/display/FileFieldDisplay.js +1 -1
  64. package/dist/components/fields/display/GeoPointFieldDisplay.js +1 -1
  65. package/dist/components/fields/display/HiddenFieldDisplay.js +1 -1
  66. package/dist/components/fields/display/ImageFieldDisplay.js +1 -1
  67. package/dist/components/fields/display/LinkFieldDisplay.js +1 -1
  68. package/dist/components/fields/display/MapFieldDisplay.js +1 -1
  69. package/dist/components/fields/display/MultiDropdownDisplay.js +1 -1
  70. package/dist/components/fields/display/MultiInputTextFieldDisplay.js +1 -1
  71. package/dist/components/fields/display/NumberFieldDisplay.js +1 -1
  72. package/dist/components/fields/display/PasswordFieldDisplay.js +1 -1
  73. package/dist/components/fields/display/PhoneNumberDisplay.js +1 -1
  74. package/dist/components/fields/display/RadioFieldDisplay.js +1 -1
  75. package/dist/components/fields/display/RangeFieldDisplay.js +1 -1
  76. package/dist/components/fields/display/ReferenceFieldDisplay.js +1 -1
  77. package/dist/components/fields/display/RichTextDisplay.js +2 -2
  78. package/dist/components/fields/display/TextAreaDisplay.js +1 -1
  79. package/dist/components/fields/display/TextFieldDisplay.js +1 -1
  80. package/dist/components/fields/display/TimestampFieldDisplay.js +1 -1
  81. package/dist/components/fields/display/index.js +1 -1
  82. package/dist/components/form/fields/AddressFieldComponent.js +1 -1
  83. package/dist/components/form/fields/AvatarFieldComponent.js +1 -1
  84. package/dist/components/form/fields/BadgeFieldComponent.js +1 -1
  85. package/dist/components/form/fields/ButtonFieldComponent.js +1 -1
  86. package/dist/components/form/fields/CheckboxFieldComponent.js +1 -1
  87. package/dist/components/form/fields/ComboboxComponent.js +1 -1
  88. package/dist/components/form/fields/CurrencyFieldComponent.js +1 -1
  89. package/dist/components/form/fields/DateFieldComponent.js +1 -1
  90. package/dist/components/form/fields/DocumentFieldComponent.js +1 -1
  91. package/dist/components/form/fields/DropdownComponent.js +1 -1
  92. package/dist/components/form/fields/DurationFieldComponent.js +1 -1
  93. package/dist/components/form/fields/FileFieldComponent.js +1 -1
  94. package/dist/components/form/fields/GdprConsentFieldComponent.js +1 -1
  95. package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
  96. package/dist/components/form/fields/HiddenFieldComponent.js +1 -1
  97. package/dist/components/form/fields/ImageFieldComponent.js +1 -1
  98. package/dist/components/form/fields/MapFieldComponent.js +1 -1
  99. package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
  100. package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
  101. package/dist/components/form/fields/NumberFieldComponent.js +1 -1
  102. package/dist/components/form/fields/PasswordFieldComponent.js +1 -1
  103. package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
  104. package/dist/components/form/fields/PriceFieldComponent.js +1 -1
  105. package/dist/components/form/fields/RadioFieldComponent.js +1 -1
  106. package/dist/components/form/fields/RangeFieldComponent.js +1 -1
  107. package/dist/components/form/fields/RatingFieldComponent.js +1 -1
  108. package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
  109. package/dist/components/form/fields/RichTextComponent.js +1 -1
  110. package/dist/components/form/fields/SwitchFieldComponent.js +1 -1
  111. package/dist/components/form/fields/TextAreaComponent.js +1 -1
  112. package/dist/components/form/fields/TextFieldComponent.js +1 -1
  113. package/dist/components/form/fields/TimestampFieldComponent.js +1 -1
  114. package/dist/components/form/fields/index.js +1 -1
  115. package/dist/components/form/fields/internal/TiptapEditor.js +2 -2
  116. package/dist/components/form/internal/ImageViewerDialog.js +1 -1
  117. package/dist/components/index.js +1 -1
  118. package/dist/contexts/UploadContext.js +1 -1
  119. package/dist/contexts/index.js +1 -1
  120. package/dist/fieldTypeRegistry.js +1 -1
  121. package/dist/fieldTypeRegistry.store.js +1 -1
  122. package/dist/forms/hooks/index.js +1 -1
  123. package/dist/forms/hooks/useController.js +1 -1
  124. package/dist/forms/hooks/useEntityField.js +1 -1
  125. package/dist/forms/hooks/useEntityForm.d.ts.map +1 -1
  126. package/dist/forms/hooks/useEntityForm.js +1 -1
  127. package/dist/forms/index.js +1 -1
  128. package/dist/forms/utils/buildInitialValues.js +1 -1
  129. package/dist/forms/utils/getFieldsForOperation.js +1 -1
  130. package/dist/forms/utils/index.js +1 -1
  131. package/dist/forms/utils/isFieldEditable.js +1 -1
  132. package/dist/forms/utils/translateFieldLabel.js +1 -1
  133. package/dist/forms/utils/validateEntity.js +1 -1
  134. package/dist/hooks/index.js +1 -1
  135. package/dist/hooks/useCrudFilters.js +1 -1
  136. package/dist/hooks/useEntityFavorites.js +1 -1
  137. package/dist/hooks/useFieldConditions.js +1 -1
  138. package/dist/hooks/useFileUpload.js +1 -1
  139. package/dist/hooks/useReferenceResolver.js +1 -1
  140. package/dist/hooks/useRelatedItems.js +1 -1
  141. package/dist/hooks/useUnsavedChangesWarning.js +1 -1
  142. package/dist/index.js +1 -1
  143. package/dist/registerBuiltinFieldTypes.d.ts.map +1 -1
  144. package/dist/registerBuiltinFieldTypes.js +1 -1
  145. package/dist/stores/FormStore.d.ts.map +1 -1
  146. package/dist/stores/FormStore.js +1 -1
  147. package/dist/stores/UploadStore.js +1 -1
  148. package/dist/stores/index.js +1 -1
  149. package/dist/tsconfig.tsbuildinfo +1 -1
  150. package/dist/types.js +1 -1
  151. package/dist/useBaseCrudList.js +1 -1
  152. package/dist/useCrud.js +1 -1
  153. package/dist/useCrudCardList.js +1 -1
  154. package/dist/useCrudList.js +1 -1
  155. package/dist/utils/clientListProcessing.js +1 -1
  156. package/dist/utils/collections.js +1 -1
  157. package/dist/utils/fileStorage.js +1 -1
  158. package/dist/utils/imageProcessing.js +1 -1
  159. package/dist/utils/imageStorage.js +1 -1
  160. package/dist/utils/imageUtils.js +1 -1
  161. package/dist/utils/matchesFilter.d.ts.map +1 -1
  162. package/dist/utils/matchesFilter.js +1 -1
  163. package/dist/utils/mergeWithOptimistic.js +1 -1
  164. package/dist/utils/sanitizeHtml.js +1 -1
  165. package/dist/utils/scopeUtils.js +1 -1
  166. package/dist/utils/uploadValidation.js +1 -1
  167. package/dist/workflows/WorkflowPersistence.js +1 -1
  168. package/dist/workflows/defineWorkflow.js +1 -1
  169. package/dist/workflows/index.js +1 -1
  170. package/dist/workflows/useEntityWorkflow.js +1 -1
  171. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import{toast as p}from"@donotdev/components";import{createSingleton as w,handleError as l,getQueryClient as E,getI18nInstance as y,hasProvider as C,getProvider as A,hasRestrictedVisibility as L,DEFAULT_STATUS_VALUE as T}from"@donotdev/core";import{LIST_SCHEMA_TYPE as S}from"@donotdev/core";import{CRUD_OPERATION as h}from"./types";const m=1/0,P=1e3*60*30;class D{adapter=null;store=null;security=null;currentUserId=null;_shouldShowSuccessToast(t){return t?.showSuccessToast===!0?!0:t?.showSuccessToast===!1?!1:!this.store?.getState().hideSuccessToasts}setStore(t){this.store=t}setSecurity(t){this.security=t}setCurrentUser(t){this.currentUserId=t}_getPiiFields(t){return t?.security?.piiFields??[]}_auditCrud(t,e,i,r){this.security&&this.security.audit({type:t,collection:e,docId:i,userId:r??this.currentUserId??void 0})}_rateLimitKey(t){return this.currentUserId?`${this.currentUserId}:${t}`:t}async _ensureAdapter(){this.adapter||await this.initialize()}_assertCanAccess(t,e){if(this.adapter&&e&&L(e)&&!this.adapter.serverSideOnly&&!this.adapter.dbLevelSecurity)throw new Error(`[dndev] Direct adapter cannot access "${t}": entity has restricted field visibility. Use a server-side adapter (FunctionsAdapter for Firebase, or SupabaseCrudAdapter with RLS enabled) to enforce field-level security (serverSideOnly = true | dbLevelSecurity = true).`)}async initialize(){if(!this.adapter){if(!C("crud"))throw new Error(`[dndev] No CRUD adapter configured. Call configureProviders({ crud: yourAdapter }) at app startup.
1
+ import{toast as w}from"@donotdev/components";import{createSingleton as A,handleError as f,getQueryClient as L,getI18nInstance as m,hasProvider as D,getProvider as T,hasRestrictedVisibility as F,DEFAULT_STATUS_VALUE as q}from"@donotdev/core";import{LIST_SCHEMA_TYPE as _}from"@donotdev/core";import{CRUD_OPERATION as y}from"./types";const S=1/0,P=1e3*60*30;class b{adapter=null;store=null;security=null;currentUserId=null;_shouldShowSuccessToast(t){return t?.showSuccessToast===!0?!0:t?.showSuccessToast===!1?!1:!this.store?.getState().hideSuccessToasts}setStore(t){this.store=t}setSecurity(t){this.security=t}setCurrentUser(t){this.currentUserId=t}_getPiiFields(t){return t?.security?.piiFields??[]}_auditCrud(t,e,s,i){this.security&&this.security.audit({type:t,collection:e,docId:s,userId:i??this.currentUserId??void 0})}_rateLimitKey(t){return this.currentUserId?`${this.currentUserId}:${t}`:t}async _ensureAdapter(){this.adapter||await this.initialize()}_assertCanAccess(t,e){if(this.adapter&&e&&F(e)&&!this.adapter.serverSideOnly&&!this.adapter.dbLevelSecurity)throw new Error(`[dndev] Direct adapter cannot access "${t}": entity has restricted field visibility. Use a server-side adapter (FunctionsAdapter for Firebase, or SupabaseCrudAdapter with RLS enabled) to enforce field-level security (serverSideOnly = true | dbLevelSecurity = true).`)}async initialize(){if(!this.adapter){if(!D("crud"))throw new Error(`[dndev] No CRUD adapter configured. Call configureProviders({ crud: yourAdapter }) at app startup.
2
2
  Examples:
3
3
  import { FirestoreAdapter } from "@donotdev/firebase";
4
4
  import { FunctionsAdapter } from "@donotdev/crud";
@@ -6,4 +6,4 @@ Examples:
6
6
 
7
7
  configureProviders({ crud: new FirestoreAdapter() }) // Firebase direct
8
8
  configureProviders({ crud: new FunctionsAdapter() }) // via callable functions
9
- configureProviders({ crud: new SupabaseCrudAdapter(sb) }) // Supabase direct (RLS)`);this.adapter=A("crud"),this.store&&this.store.getState().setCrudService(this)}}getQueryClient(){return E()}getListQueryOptions(t,e,i,r,o=S.LIST){const s=this.adapter,a=()=>this._ensureAdapter();return{queryKey:["crud",t,"query",JSON.stringify(e)],queryFn:async()=>{if(s||await a(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.query(t,e,i,o)},staleTime:r?.staleTime??m}}getDocQueryOptions(t,e,i,r){const o=this.adapter,s=()=>this._ensureAdapter();return{queryKey:["crud",t,"get",e],queryFn:async()=>{if(o||await s(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.get(t,e,i)},staleTime:r?.staleTime??m}}_updateGetCache(t,e,i,r){const o=this.getQueryClient(),s=["crud",t,"get",e];r===h.DELETE?o.removeQueries({queryKey:s}):r===h.SET&&i?o.setQueryData(s,i):(r===h.UPDATE||r===h.ADD)&&i&&o.setQueryData(s,a=>a?{...a,...i}:i)}_updateListCaches(t,e,i,r){const o=this.getQueryClient();this._updateGetCache(t,e,i,r),o.setQueriesData({queryKey:["crud",t]},s=>{if(s&&typeof s=="object"&&"items"in s){const a=s;let n=a.items;return r===h.DELETE?(n=a.items.filter(c=>c!=null&&typeof c=="object"&&c.id!==e),{...a,items:n,total:Math.max(0,(a.total??n.length)-1)}):r===h.ADD&&i?(n=[...a.items,{...i,id:e}],{...a,items:n,total:(a.total??a.items.length)+1}):(r===h.UPDATE||r===h.SET)&&i&&a.items.some(c=>c!=null&&typeof c=="object"&&c.id===e)?(n=a.items.map(c=>c==null||typeof c!="object"||c.id!==e?c:r===h.SET?{...i,id:e}:{...c,...i}),{...a,items:n}):s}if(Array.isArray(s)){if(r===h.DELETE)return s.filter(a=>a.id!==e);if(r===h.ADD&&i)return[...s,{...i,id:e}];if((r===h.UPDATE||r===h.SET)&&i)return s.some(a=>a!=null&&typeof a=="object"&&a.id===e)?s.map(a=>a==null||typeof a!="object"||a.id!==e?a:r===h.SET?{...i,id:e}:{...a,...i}):s}return s})}_checkUniquenessFromCache(t,e,i){const r=i.metadata?.uniqueKeys;if(!r||r.length===0)return null;const o=this.getQueryClient().getQueriesData({queryKey:["crud",t]}),s=[];for(const[,n]of o)n&&typeof n=="object"&&"items"in n?s.push(...n.items):Array.isArray(n)&&s.push(...n);if(s.length===0)return null;const a=e;for(const n of r){if(!n.fields.every(u=>a[u]!=null&&a[u]!==""))continue;const c=s.find(u=>n.fields.every(d=>{const g=typeof a[d]=="string"?a[d].toLowerCase():a[d],f=typeof u[d]=="string"?u[d].toLowerCase():u[d];return g===f}));if(c){if(n.findOrCreate)return c.id;const u=n.fields.join(" + ");throw l(new Error(n.errorMessage||`Duplicate ${u}`),{userMessage:n.errorMessage||`A record with this ${u} already exists`,showNotification:!0})}}return null}_getItemFromListCache(t,e){const i=this.getQueryClient().getQueriesData({queryKey:["crud",t]});for(const[,r]of i)if(r?.items){const o=r.items.find(s=>s.id===e);if(o)return o}return null}async invalidateCollection(t){await this.getQueryClient().invalidateQueries({queryKey:["crud",t]})}async get(t,e,i,r){if(await this._ensureAdapter(),r?.noCache)return this._getFromAdapter(t,e,i);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"get",e],queryFn:()=>this._getFromAdapter(t,e,i,!1),staleTime:r?.staleTime??m})}catch(o){const s=l(o,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,s),s}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _getFromAdapter(t,e,i,r=!0){this.store&&r&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,i);const o=await this.adapter.get(t,e,i);if(o&&this.security){const s=this._getPiiFields(i);if(s.length>0)return this.security.decryptPii(o,s)}return o}catch(o){const s=l(o,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,s),s}finally{this.store&&r&&this.store.getState().setLoading(t,!1)}}async query(t,e,i,r,o=S.LIST){if(await this._ensureAdapter(),r?.noCache)return this._queryFromAdapter(t,e,i,!0,o);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"query",JSON.stringify(e)],queryFn:()=>this._queryFromAdapter(t,e,i,!1,o),staleTime:r?.staleTime??m})}catch(s){const a=l(s,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,a),a}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _queryFromAdapter(t,e,i,r=!0,o=S.LIST){this.store&&r&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,i);const s=await this.adapter.query(t,e,i,o);if(this.security&&s.items.length>0){const a=this._getPiiFields(i);a.length>0&&(s.items=s.items.map(n=>this.security.decryptPii(n,a)))}return s}catch(s){const a=l(s,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,a),a}finally{this.store&&r&&this.store.getState().setLoading(t,!1)}}_getEntityName(t){const e=y();let i=`entity-${t}`,r=e.t("name",{ns:i,defaultValue:null});return r&&r!=="name"&&r!==`${i}:name`||t.endsWith("s")&&t.length>1&&(i=`entity-${t.slice(0,-1)}`,r=e.t("name",{ns:i,defaultValue:null}),r&&r!=="name"&&r!==`${i}:name`)?r:t}async set(t,e,i,r,o){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const s=this.getQueryClient().getQueryData(["crud",t,"get",e])??null;this.store&&this.store.getState().updateOptimistic(t,e,i,s);try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,r),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const a=this._getPiiFields(r),n=a.length>0&&this.security?this.security.encryptPii(i,a):i;if(await this.adapter.set(t,e,n,r),this._updateListCaches(t,e,i,h.SET),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(o)){const c=y(),u=this._getEntityName(t);p("success",c.t("messages.updateSuccess",{ns:"crud",entity:u}))}}catch(a){s&&this._updateListCaches(t,e,s,h.SET),this.store&&this.store.getState().rejectUpdate(t,e);const n=l(a,{userMessage:`Failed to save ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,n),n}finally{this.store&&this.store.getState().setLoading(t,!1)}}async update(t,e,i,r,o){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const s=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e),a=s?{...s,...i}:{...i,id:e};this.store&&this.store.getState().updateOptimistic(t,e,a,s??null);try{if(!this.adapter)throw new Error("Adapter not initialized");r&&this._assertCanAccess(t,r),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const n=r?this._getPiiFields(r):[],c=n.length>0&&this.security?this.security.encryptPii(i,n):i;if(await this.adapter.update(t,e,c),this._updateListCaches(t,e,a,h.UPDATE),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(o)){const u=y(),d=this._getEntityName(t);p("success",u.t("messages.updateSuccess",{ns:"crud",entity:d}))}}catch(n){s?this._updateListCaches(t,e,s,h.UPDATE):this.invalidateCollection(t),this.store&&this.store.getState().rejectUpdate(t,e);const c=l(n,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,c),c}finally{this.store&&this.store.getState().setLoading(t,!1)}}async delete(t,e,i){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const r=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e);this.store&&r&&this.store.getState().deleteOptimistic(t,e,r);try{if(!this.adapter)throw new Error("Adapter not initialized");if(this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write"),await this.adapter.delete(t,e),this._updateListCaches(t,e,null,h.DELETE),this.store&&this.store.getState().confirmDelete(t,e),this._auditCrud("crud.delete",t,e),this.security?.recordAnomaly?.("bulk.deletes",this.currentUserId??void 0),this._shouldShowSuccessToast(i)){const o=y(),s=this._getEntityName(t);p("success",o.t("messages.deleteSuccess",{ns:"crud",entity:s}))}}catch(o){r&&this._updateListCaches(t,e,r,h.ADD),this.store&&this.store.getState().rejectDelete(t,e);const s=l(o,{userMessage:`Failed to delete ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,s),s}finally{this.store&&this.store.getState().setLoading(t,!1)}}async add(t,e,i,r){await this._ensureAdapter();const o=this._checkUniquenessFromCache(t,e,i);if(o)return o;this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const s=`temp_${crypto.randomUUID()}`;this.store&&this.store.getState().addOptimistic(t,s,{...e,id:s});try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,i),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const a=this._getPiiFields(i),n=a.length>0&&this.security?this.security.encryptPii(e,a):e,c=n;(c.status===void 0||c.status===null)&&(c.status=T);const u=await this.adapter.add(t,n,i),d=u.id,g=u.data;if(this._updateListCaches(t,s,null,h.DELETE),this._updateListCaches(t,d,g,h.ADD),this.store&&this.store.getState().confirmOptimistic(t,s,d,g),this._auditCrud("crud.create",t,d),this._shouldShowSuccessToast(r)){const f=y(),_=this._getEntityName(t);p("success",f.t("messages.createSuccess",{ns:"crud",entity:_}))}return d}catch(a){this._updateListCaches(t,s,null,h.DELETE),this.store&&this.store.getState().rejectOptimistic(t,s);const n=l(a,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,n),n}finally{this.store&&this.store.getState().setLoading(t,!1)}}subscribe(t,e,i,r){if(!this.adapter){let o=!1,s=null;return this._ensureAdapter().then(()=>{o||(s=this._subscribeSync(t,e,i,r))}).catch(a=>{o||i(null,l(a))}),()=>{o=!0,s?.()}}return this._subscribeSync(t,e,i,r)}_subscribeSync(t,e,i,r){try{const o=this.adapter;return o?o.subscribe?(this._assertCanAccess(t,r),o.subscribe(t,e,(s,a)=>{s&&this.getQueryClient().setQueryData(["crud",t,"get",e],s),i(s,a)},r)):()=>{}:(i(null,new Error("Adapter not initialized")),()=>{})}catch(o){return i(null,l(o)),()=>{}}}subscribeToCollection(t,e,i,r){if(!this.adapter){let o=!1,s=null;return this._ensureAdapter().then(()=>{o||(s=this._subscribeToCollectionSync(t,e,i,r))}).catch(a=>{o||i([],l(a))}),()=>{o=!0,s?.()}}return this._subscribeToCollectionSync(t,e,i,r)}_subscribeToCollectionSync(t,e,i,r){try{const o=this.adapter;return o?o.subscribeToCollection?(this._assertCanAccess(t,r),o.subscribeToCollection(t,e,(s,a)=>{s&&this.getQueryClient().setQueryData(["crud",t,"query",JSON.stringify(e)],n=>n?{...n,items:s}:{items:s}),i(s,a)},r)):()=>{}:(i([],new Error("Adapter not initialized")),()=>{})}catch(o){return i([],l(o)),()=>{}}}async addOptimistic(t,e,i,r){await this._ensureAdapter();const o=this._checkUniquenessFromCache(t,e,i);if(o)return{...e,id:o};this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const s=`temp_${crypto.randomUUID()}`,a={...e,id:s,_optimistic:!0};this.store&&this.store.getState().addOptimistic(t,s,a);try{if(!this.adapter)throw new Error("Adapter not initialized");const n=await this.adapter.add(t,e,i),c=n.id,u=n.data;if(this._updateListCaches(t,s,null,h.DELETE),this._updateListCaches(t,c,u,h.ADD),this.store&&this.store.getState().confirmOptimistic(t,s,c,u),this._auditCrud("crud.create",t,c),this._shouldShowSuccessToast(r)){const d=y(),g=this._getEntityName(t);p("success",d.t("messages.createSuccess",{ns:"crud",entity:g}))}return u}catch(n){throw this._updateListCaches(t,s,null,h.DELETE),this.store&&this.store.getState().rejectOptimistic(t,s),l(n,{userMessage:`Failed to create ${t}`,showNotification:!0})}}async updateOptimistic(t,e,i,r,o){await this._ensureAdapter(),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const s=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e),a=s?{...s,...i,_optimistic:!0}:{...i,id:e,_optimistic:!0};this.store&&s&&this.store.getState().updateOptimistic(t,e,a,s);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.update(t,e,i);const{_optimistic:n,...c}=a;if(this._updateListCaches(t,e,c,h.UPDATE),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(o)){const u=y(),d=this._getEntityName(t);p("success",u.t("messages.updateSuccess",{ns:"crud",entity:d}))}return c}catch(n){throw s&&this._updateListCaches(t,e,s,h.UPDATE),this.store&&this.store.getState().rejectUpdate(t,e),l(n,{userMessage:`Failed to update ${t}`,showNotification:!0})}}async deleteOptimistic(t,e,i){await this._ensureAdapter(),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const r=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e);this.store&&r&&this.store.getState().deleteOptimistic(t,e,r);try{if(!this.adapter)throw new Error("Adapter not initialized");if(await this.adapter.delete(t,e),this._updateListCaches(t,e,null,h.DELETE),this.store&&this.store.getState().confirmDelete(t,e),this._auditCrud("crud.delete",t,e),this.security?.recordAnomaly?.("bulk.deletes",this.currentUserId??void 0),this._shouldShowSuccessToast(i)){const o=y(),s=this._getEntityName(t);p("success",o.t("messages.deleteSuccess",{ns:"crud",entity:s}))}}catch(o){throw r&&this._updateListCaches(t,e,r,h.ADD),this.store&&this.store.getState().rejectDelete(t,e),l(o,{userMessage:`Failed to delete ${t}`,showNotification:!0})}}}const b=w(()=>new D);export{b as getCrudService};
9
+ configureProviders({ crud: new SupabaseCrudAdapter(sb) }) // Supabase direct (RLS)`);this.adapter=T("crud"),this.store&&this.store.getState().setCrudService(this)}}getQueryClient(){return L()}getListQueryOptions(t,e,s,i,a=_.LIST){const r=this.adapter,u=()=>this._ensureAdapter();return{queryKey:["crud",t,"query",JSON.stringify(e)],queryFn:async()=>{if(r||await u(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.query(t,e,s,a)},staleTime:i?.staleTime??S}}getDocQueryOptions(t,e,s,i){const a=this.adapter,r=()=>this._ensureAdapter();return{queryKey:["crud",t,"get",e],queryFn:async()=>{if(a||await r(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.get(t,e,s)},staleTime:i?.staleTime??S}}_updateGetCache(t,e,s,i){const a=this.getQueryClient(),r=["crud",t,"get",e];i===y.DELETE?a.removeQueries({queryKey:r}):i===y.SET&&s?a.setQueryData(r,s):(i===y.UPDATE||i===y.ADD)&&s&&a.setQueryData(r,u=>u?{...u,...s}:s)}_updateListCaches(t,e,s,i){const a=this.getQueryClient();this._updateGetCache(t,e,s,i),a.setQueriesData({queryKey:["crud",t]},r=>{if(r&&typeof r=="object"&&"items"in r){const u=r;let n=u.items;return i===y.DELETE?(n=u.items.filter(d=>d!=null&&typeof d=="object"&&d.id!==e),{...u,items:n,total:Math.max(0,(u.total??n.length)-1)}):i===y.ADD&&s?(n=[...u.items,{...s,id:e}],{...u,items:n,total:(u.total??u.items.length)+1}):(i===y.UPDATE||i===y.SET)&&s&&u.items.some(h=>h!=null&&typeof h=="object"&&h.id===e)?(n=u.items.map(h=>h==null||typeof h!="object"||h.id!==e?h:i===y.SET?{...s,id:e}:{...h,...s}),{...u,items:n}):r}if(Array.isArray(r)){if(i===y.DELETE)return r.filter(u=>u.id!==e);if(i===y.ADD&&s)return[...r,{...s,id:e}];if((i===y.UPDATE||i===y.SET)&&s)return r.some(n=>n!=null&&typeof n=="object"&&n.id===e)?r.map(n=>n==null||typeof n!="object"||n.id!==e?n:i===y.SET?{...s,id:e}:{...n,...s}):r}return r})}_checkUniquenessFromCache(t,e,s){const a=s.metadata?.uniqueKeys;if(!a||a.length===0)return null;const u=this.getQueryClient().getQueriesData({queryKey:["crud",t]}),n=[];for(const[,h]of u)h&&typeof h=="object"&&"items"in h?n.push(...h.items):Array.isArray(h)&&n.push(...h);if(n.length===0)return null;const d=e;for(const h of a){if(!h.fields.every(g=>d[g]!=null&&d[g]!==""))continue;const p=n.find(g=>h.fields.every(c=>{const E=typeof d[c]=="string"?d[c].toLowerCase():d[c],C=typeof g[c]=="string"?g[c].toLowerCase():g[c];return E===C}));if(p){if(h.findOrCreate)return p.id;const g=h.fields.join(" + ");throw f(new Error(h.errorMessage||`Duplicate ${g}`),{userMessage:h.errorMessage||`A record with this ${g} already exists`,showNotification:!0})}}return null}_getItemFromListCache(t,e){const i=this.getQueryClient().getQueriesData({queryKey:["crud",t]});for(const[,a]of i)if(a?.items){const r=a.items.find(u=>u.id===e);if(r)return r}return null}async invalidateCollection(t){await this.getQueryClient().invalidateQueries({queryKey:["crud",t]})}async get(t,e,s,i){if(await this._ensureAdapter(),i?.noCache)return this._getFromAdapter(t,e,s);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"get",e],queryFn:()=>this._getFromAdapter(t,e,s,!1),staleTime:i?.staleTime??S})}catch(a){const r=f(a,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _getFromAdapter(t,e,s,i=!0){this.store&&i&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,s);const a=await this.adapter.get(t,e,s);if(a&&this.security){const r=this._getPiiFields(s);if(r.length>0)return this.security.decryptPii(a,r)}return a}catch(a){const r=f(a,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&i&&this.store.getState().setLoading(t,!1)}}async query(t,e,s,i,a=_.LIST){if(await this._ensureAdapter(),i?.noCache)return this._queryFromAdapter(t,e,s,!0,a);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"query",JSON.stringify(e)],queryFn:()=>this._queryFromAdapter(t,e,s,!1,a),staleTime:i?.staleTime??S})}catch(r){const u=f(r,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,u),u}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _queryFromAdapter(t,e,s,i=!0,a=_.LIST){this.store&&i&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,s);const r=await this.adapter.query(t,e,s,a);if(this.security&&r.items.length>0){const u=this._getPiiFields(s);u.length>0&&(r.items=r.items.map(n=>this.security.decryptPii(n,u)))}return r}catch(r){const u=f(r,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,u),u}finally{this.store&&i&&this.store.getState().setLoading(t,!1)}}_getEntityName(t){const e=m();let s=`entity-${t}`,i=e.t("name",{ns:s,defaultValue:null});return i&&i!=="name"&&i!==`${s}:name`||t.endsWith("s")&&t.length>1&&(s=`entity-${t.slice(0,-1)}`,i=e.t("name",{ns:s,defaultValue:null}),i&&i!=="name"&&i!==`${s}:name`)?i:t}async set(t,e,s,i,a){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const u=this.getQueryClient().getQueryData(["crud",t,"get",e])??null;this.store&&this.store.getState().updateOptimistic(t,e,s,u);try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,i),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const n=this._getPiiFields(i),d=n.length>0&&this.security?this.security.encryptPii(s,n):s;if(await this.adapter.set(t,e,d,i),this._updateListCaches(t,e,s,y.SET),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(a)){const h=m(),o=this._getEntityName(t);w("success",h.t("messages.updateSuccess",{ns:"crud",entity:o}))}}catch(n){u&&this._updateListCaches(t,e,u,y.SET),this.store&&this.store.getState().rejectUpdate(t,e);const d=f(n,{userMessage:`Failed to save ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,d),d}finally{this.store&&this.store.getState().setLoading(t,!1)}}async update(t,e,s,i,a){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const u=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e),n=u?{...u,...s}:{...s,id:e};this.store&&this.store.getState().updateOptimistic(t,e,n,u??null);try{if(!this.adapter)throw new Error("Adapter not initialized");i&&this._assertCanAccess(t,i),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const d=i?this._getPiiFields(i):[],h=d.length>0&&this.security?this.security.encryptPii(s,d):s;if(await this.adapter.update(t,e,h),this._updateListCaches(t,e,n,y.UPDATE),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(a)){const o=m(),p=this._getEntityName(t);w("success",o.t("messages.updateSuccess",{ns:"crud",entity:p}))}}catch(d){u?this._updateListCaches(t,e,u,y.UPDATE):this.invalidateCollection(t),this.store&&this.store.getState().rejectUpdate(t,e);const h=f(d,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,h),h}finally{this.store&&this.store.getState().setLoading(t,!1)}}async delete(t,e,s){await this._ensureAdapter(),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const a=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e);this.store&&a&&this.store.getState().deleteOptimistic(t,e,a);try{if(!this.adapter)throw new Error("Adapter not initialized");if(this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write"),await this.adapter.delete(t,e),this._updateListCaches(t,e,null,y.DELETE),this.store&&this.store.getState().confirmDelete(t,e),this._auditCrud("crud.delete",t,e),this.security?.recordAnomaly?.("bulk.deletes",this.currentUserId??void 0),this._shouldShowSuccessToast(s)){const r=m(),u=this._getEntityName(t);w("success",r.t("messages.deleteSuccess",{ns:"crud",entity:u}))}}catch(r){a&&this._updateListCaches(t,e,a,y.ADD),this.store&&this.store.getState().rejectDelete(t,e);const u=f(r,{userMessage:`Failed to delete ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,u),u}finally{this.store&&this.store.getState().setLoading(t,!1)}}async add(t,e,s,i){await this._ensureAdapter();const a=this._checkUniquenessFromCache(t,e,s);if(a)return a;this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const r=`temp_${crypto.randomUUID()}`;this.store&&this.store.getState().addOptimistic(t,r,{...e,id:r});try{if(!this.adapter)throw new Error("Adapter not initialized");this._assertCanAccess(t,s),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const u=this._getPiiFields(s),n=u.length>0&&this.security?this.security.encryptPii(e,u):e,d=n;(d.status===void 0||d.status===null)&&(d.status=q);const h=await this.adapter.add(t,n,s),o=h.id,p=h.data;if(this._updateListCaches(t,r,null,y.DELETE),this._updateListCaches(t,o,p,y.ADD),this.store&&this.store.getState().confirmOptimistic(t,r,o,p),this._auditCrud("crud.create",t,o),this._shouldShowSuccessToast(i)){const g=m(),c=this._getEntityName(t);w("success",g.t("messages.createSuccess",{ns:"crud",entity:c}))}return o}catch(u){this._updateListCaches(t,r,null,y.DELETE),this.store&&this.store.getState().rejectOptimistic(t,r);const n=f(u,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,n),n}finally{this.store&&this.store.getState().setLoading(t,!1)}}subscribe(t,e,s,i){if(!this.adapter){let a=!1,r=null;return this._ensureAdapter().then(()=>{a||(r=this._subscribeSync(t,e,s,i))}).catch(u=>{a||s(null,f(u))}),()=>{a=!0,r?.()}}return this._subscribeSync(t,e,s,i)}_subscribeSync(t,e,s,i){try{const a=this.adapter;return a?a.subscribe?(this._assertCanAccess(t,i),a.subscribe(t,e,(r,u)=>{r&&this.getQueryClient().setQueryData(["crud",t,"get",e],r),s(r,u)},i)):()=>{}:(s(null,new Error("Adapter not initialized")),()=>{})}catch(a){return s(null,f(a)),()=>{}}}subscribeToCollection(t,e,s,i){if(!this.adapter){let a=!1,r=null;return this._ensureAdapter().then(()=>{a||(r=this._subscribeToCollectionSync(t,e,s,i))}).catch(u=>{a||s([],f(u))}),()=>{a=!0,r?.()}}return this._subscribeToCollectionSync(t,e,s,i)}_subscribeToCollectionSync(t,e,s,i){try{const a=this.adapter;return a?a.subscribeToCollection?(this._assertCanAccess(t,i),a.subscribeToCollection(t,e,(r,u)=>{r&&this.getQueryClient().setQueryData(["crud",t,"query",JSON.stringify(e)],n=>n?{...n,items:r}:{items:r}),s(r,u)},i)):()=>{}:(s([],new Error("Adapter not initialized")),()=>{})}catch(a){return s([],f(a)),()=>{}}}async addOptimistic(t,e,s,i){await this._ensureAdapter();const a=this._checkUniquenessFromCache(t,e,s);if(a)return{...e,id:a};this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const r=`temp_${crypto.randomUUID()}`,u={...e,id:r,_optimistic:!0};this.store&&this.store.getState().addOptimistic(t,r,u);try{if(!this.adapter)throw new Error("Adapter not initialized");const n=await this.adapter.add(t,e,s),d=n.id,h=n.data;if(this._updateListCaches(t,r,null,y.DELETE),this._updateListCaches(t,d,h,y.ADD),this.store&&this.store.getState().confirmOptimistic(t,r,d,h),this._auditCrud("crud.create",t,d),this._shouldShowSuccessToast(i)){const o=m(),p=this._getEntityName(t);w("success",o.t("messages.createSuccess",{ns:"crud",entity:p}))}return h}catch(n){throw this._updateListCaches(t,r,null,y.DELETE),this.store&&this.store.getState().rejectOptimistic(t,r),f(n,{userMessage:`Failed to create ${t}`,showNotification:!0})}}async updateOptimistic(t,e,s,i,a){await this._ensureAdapter(),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const u=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e),n=u?{...u,...s,_optimistic:!0}:{...s,id:e,_optimistic:!0};this.store&&u&&this.store.getState().updateOptimistic(t,e,n,u);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.update(t,e,s);const{_optimistic:d,...h}=n;if(this._updateListCaches(t,e,h,y.UPDATE),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(a)){const o=m(),p=this._getEntityName(t);w("success",o.t("messages.updateSuccess",{ns:"crud",entity:p}))}return h}catch(d){throw u&&this._updateListCaches(t,e,u,y.UPDATE),this.store&&this.store.getState().rejectUpdate(t,e),f(d,{userMessage:`Failed to update ${t}`,showNotification:!0})}}async deleteOptimistic(t,e,s){await this._ensureAdapter(),this.security&&await this.security.checkRateLimit(this._rateLimitKey(t),"write");const a=this.getQueryClient().getQueryData(["crud",t,"get",e])??this._getItemFromListCache(t,e);this.store&&a&&this.store.getState().deleteOptimistic(t,e,a);try{if(!this.adapter)throw new Error("Adapter not initialized");if(await this.adapter.delete(t,e),this._updateListCaches(t,e,null,y.DELETE),this.store&&this.store.getState().confirmDelete(t,e),this._auditCrud("crud.delete",t,e),this.security?.recordAnomaly?.("bulk.deletes",this.currentUserId??void 0),this._shouldShowSuccessToast(s)){const r=m(),u=this._getEntityName(t);w("success",r.t("messages.deleteSuccess",{ns:"crud",entity:u}))}}catch(r){throw a&&this._updateListCaches(t,e,a,y.ADD),this.store&&this.store.getState().rejectDelete(t,e),f(r,{userMessage:`Failed to delete ${t}`,showNotification:!0})}}}const l=A(()=>new b);export{l as getCrudService};
package/dist/CrudStore.js CHANGED
@@ -1 +1 @@
1
- import{createDoNotDevStore as d}from"@donotdev/core";import{OPTIMISTIC_STATUSES as u,CRUD_OPERATION as a}from"./types";const D={filters:{},showFavoritesOnly:!1};function r(){return{loading:!1,error:null,lastUpdated:0,optimistic:{},ui:{...D}}}const f={crudService:null,hideSuccessToasts:!1,collections:{}},E=d({name:"crud-store",createStore:(e,l)=>({...f,setCrudService:t=>{e({crudService:t})},setHideSuccessToasts:t=>{e({hideSuccessToasts:t})},setLoading:(t,c)=>{e(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,loading:c}}}})},setError:(t,c)=>{e(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,error:c,loading:!1}}}})},setFilters:(t,c)=>{e(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,ui:{...i.ui,filters:c}}}}})},setShowFavoritesOnly:(t,c)=>{e(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,ui:{...i.ui,showFavoritesOnly:c}}}}})},getFilters:t=>l().collections[t]?.ui?.filters||{},getShowFavoritesOnly:t=>l().collections[t]?.ui?.showFavoritesOnly||!1,clearCollection:t=>{e(c=>{const{[t]:o,...i}=c.collections;return{collections:i}})},clearError:t=>{e(c=>{const o=c.collections[t];return o?{collections:{...c.collections,[t]:{...o,error:null}}}:c})},addOptimistic:(t,c,o)=>{e(i=>{const s=i.collections[t]||r();return{collections:{...i.collections,[t]:{...s,optimistic:{...s.optimistic,[c]:{tempId:c,originalData:null,optimisticData:o,status:u.PENDING,operation:a.ADD}},lastUpdated:Date.now()}}}})},confirmOptimistic:(t,c,o,i)=>{e(s=>{const n=s.collections[t];if(!n)return s;const{[c]:p,...m}=n.optimistic;return{collections:{...s.collections,[t]:{...n,optimistic:m,lastUpdated:Date.now()}}}})},rejectOptimistic:(t,c)=>{e(o=>{const i=o.collections[t];if(!i)return o;const{[c]:s,...n}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:n,lastUpdated:Date.now()}}}})},updateOptimistic:(t,c,o,i)=>{e(s=>{const n=s.collections[t]||r();return{collections:{...s.collections,[t]:{...n,optimistic:{...n.optimistic,[c]:{tempId:c,originalData:i,optimisticData:o,status:u.PENDING,operation:a.UPDATE}},lastUpdated:Date.now()}}}})},confirmUpdate:(t,c)=>{e(o=>{const i=o.collections[t];if(!i)return o;const{[c]:s,...n}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:n}}}})},rejectUpdate:(t,c)=>{e(o=>{const i=o.collections[t];if(!i)return o;const s=i.optimistic[c];if(!s||s.operation!==a.UPDATE)return o;const{[c]:n,...p}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:p,lastUpdated:Date.now()}}}})},deleteOptimistic:(t,c,o)=>{e(i=>{const s=i.collections[t];return s?{collections:{...i.collections,[t]:{...s,optimistic:{...s.optimistic,[c]:{tempId:c,originalData:o,optimisticData:null,status:u.PENDING,operation:a.DELETE}},lastUpdated:Date.now()}}}:i})},confirmDelete:(t,c)=>{e(o=>{const i=o.collections[t];if(!i)return o;const{[c]:s,...n}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:n}}}})},rejectDelete:(t,c)=>{e(o=>{const i=o.collections[t];if(!i)return o;const s=i.optimistic[c];if(!s||s.operation!==a.DELETE)return o;const{[c]:n,...p}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:p,lastUpdated:Date.now()}}}})},getLoading:t=>l().collections[t]?.loading||!1,getError:t=>l().collections[t]?.error||null,isOptimistic:(t,c)=>l().collections[t]?.optimistic[c]?.status==="pending",getOptimisticStatus:(t,c)=>l().collections[t]?.optimistic[c]?.status??null,getOptimisticData:(t,c)=>l().collections[t]?.optimistic[c]?.optimisticData??null})});export{E as useCrudStore};
1
+ import{createDoNotDevStore as d}from"@donotdev/core";import{OPTIMISTIC_STATUSES as m,CRUD_OPERATION as a}from"./types";const S={filters:{},showFavoritesOnly:!1};function r(){return{loading:!1,error:null,lastUpdated:0,optimistic:{},ui:{...S}}}const D={crudService:null,hideSuccessToasts:!1,collections:{}},E=d({name:"crud-store",createStore:(n,s)=>({...D,setCrudService:t=>{n({crudService:t})},setHideSuccessToasts:t=>{n({hideSuccessToasts:t})},setLoading:(t,c)=>{n(i=>{const o=i.collections[t]||r();return{collections:{...i.collections,[t]:{...o,loading:c}}}})},setError:(t,c)=>{n(i=>{const o=i.collections[t]||r();return{collections:{...i.collections,[t]:{...o,error:c,loading:!1}}}})},setFilters:(t,c)=>{n(i=>{const o=i.collections[t]||r();return{collections:{...i.collections,[t]:{...o,ui:{...o.ui,filters:c}}}}})},setShowFavoritesOnly:(t,c)=>{n(i=>{const o=i.collections[t]||r();return{collections:{...i.collections,[t]:{...o,ui:{...o.ui,showFavoritesOnly:c}}}}})},getFilters:t=>s().collections[t]?.ui?.filters||{},getShowFavoritesOnly:t=>s().collections[t]?.ui?.showFavoritesOnly||!1,clearCollection:t=>{n(c=>{const{[t]:i,...o}=c.collections;return{collections:o}})},clearError:t=>{n(c=>{const i=c.collections[t];return i?{collections:{...c.collections,[t]:{...i,error:null}}}:c})},addOptimistic:(t,c,i)=>{n(o=>{const e=o.collections[t]||r();return{collections:{...o.collections,[t]:{...e,optimistic:{...e.optimistic,[c]:{tempId:c,originalData:null,optimisticData:i,status:m.PENDING,operation:a.ADD}},lastUpdated:Date.now()}}}})},confirmOptimistic:(t,c,i,o)=>{n(e=>{const l=e.collections[t];if(!l)return e;const{[c]:p,...u}=l.optimistic;return{collections:{...e.collections,[t]:{...l,optimistic:u,lastUpdated:Date.now()}}}})},rejectOptimistic:(t,c)=>{n(i=>{const o=i.collections[t];if(!o)return i;const{[c]:e,...l}=o.optimistic;return{collections:{...i.collections,[t]:{...o,optimistic:l,lastUpdated:Date.now()}}}})},updateOptimistic:(t,c,i,o)=>{n(e=>{const l=e.collections[t]||r();return{collections:{...e.collections,[t]:{...l,optimistic:{...l.optimistic,[c]:{tempId:c,originalData:o,optimisticData:i,status:m.PENDING,operation:a.UPDATE}},lastUpdated:Date.now()}}}})},confirmUpdate:(t,c)=>{n(i=>{const o=i.collections[t];if(!o)return i;const{[c]:e,...l}=o.optimistic;return{collections:{...i.collections,[t]:{...o,optimistic:l}}}})},rejectUpdate:(t,c)=>{n(i=>{const o=i.collections[t];if(!o)return i;const e=o.optimistic[c];if(!e||e.operation!==a.UPDATE)return i;const{[c]:l,...p}=o.optimistic;return{collections:{...i.collections,[t]:{...o,optimistic:p,lastUpdated:Date.now()}}}})},deleteOptimistic:(t,c,i)=>{n(o=>{const e=o.collections[t];return e?{collections:{...o.collections,[t]:{...e,optimistic:{...e.optimistic,[c]:{tempId:c,originalData:i,optimisticData:null,status:m.PENDING,operation:a.DELETE}},lastUpdated:Date.now()}}}:o})},confirmDelete:(t,c)=>{n(i=>{const o=i.collections[t];if(!o)return i;const{[c]:e,...l}=o.optimistic;return{collections:{...i.collections,[t]:{...o,optimistic:l}}}})},rejectDelete:(t,c)=>{n(i=>{const o=i.collections[t];if(!o)return i;const e=o.optimistic[c];if(!e||e.operation!==a.DELETE)return i;const{[c]:l,...p}=o.optimistic;return{collections:{...i.collections,[t]:{...o,optimistic:p,lastUpdated:Date.now()}}}})},getLoading:t=>s().collections[t]?.loading||!1,getError:t=>s().collections[t]?.error||null,isOptimistic:(t,c)=>s().collections[t]?.optimistic[c]?.status==="pending",getOptimisticStatus:(t,c)=>s().collections[t]?.optimistic[c]?.status??null,getOptimisticData:(t,c)=>s().collections[t]?.optimistic[c]?.optimisticData??null})});export{E as useCrudStore};
@@ -39,10 +39,11 @@ export type CustomFilterType = 'text' | 'range' | 'select' | 'none' | 'address'
39
39
  * Optional displayFormatter so list/card/display views can render the value.
40
40
  * Optional filterable + filterType so EntityFilters can show the right filter UI.
41
41
  */
42
- export interface FieldTypeRegistration<FT extends string = string> {
42
+ export interface FieldTypeRegistration<FT extends FieldType = FieldType> {
43
43
  type: FT;
44
- controlledComponent: ComponentType<ControlledFieldProps<FieldValues, FieldType>>;
45
- uncontrolledComponent?: ComponentType<UncontrolledFieldProps>;
44
+ /** Controlled form component. Optional for display-only registrations. */
45
+ controlledComponent?: ComponentType<ControlledFieldProps<FieldValues, FT>>;
46
+ uncontrolledComponent?: ComponentType<UncontrolledFieldProps<FT>>;
46
47
  /** Formatter for list/card/display; receives (value, fieldConfig, t, options?) */
47
48
  displayFormatter?: CustomDisplayFormatter;
48
49
  /** Whether this field is filterable in list/card filters */
@@ -67,7 +68,7 @@ declare class FieldRegistry {
67
68
  * Register a custom field type (UI components only)
68
69
  * Schemas must be defined in entity.validation.schema
69
70
  */
70
- register<FT extends string>(registration: FieldTypeRegistration<FT>): void;
71
+ register<FT extends FieldType>(registration: FieldTypeRegistration<FT>): void;
71
72
  /**
72
73
  * Get controlled component
73
74
  */
@@ -154,7 +155,7 @@ export declare function getFieldRegistry(): FieldRegistry;
154
155
  * });
155
156
  * ```
156
157
  */
157
- export declare function registerFieldType<FT extends string>(registration: FieldTypeRegistration<FT>): void;
158
+ export declare function registerFieldType<FT extends FieldType>(registration: FieldTypeRegistration<FT>): void;
158
159
  /**
159
160
  * Check if a field type is registered
160
161
  */
@@ -1 +1 @@
1
- {"version":3,"file":"FieldRegistry.d.ts","sourceRoot":"","sources":["../src/FieldRegistry.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,EAAE,SAAS,SAAS,GAAG,SAAS;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;CACzB;AAYD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EAC7D,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAChD,MAAM,GAAG,YAAY,CAAC;AAE3B,gFAAgF;AAChF,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,aAAa,CAAC;AAElB;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM;IAC/D,IAAI,EAAE,EAAE,CAAC;IACT,mBAAmB,EAAE,aAAa,CAChC,oBAAoB,CAAC,WAAW,EAAE,SAAS,CAAC,CAC7C,CAAC;IACF,qBAAqB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC9D,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;GAGG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAG9B;IACJ,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IAEJ;;;OAGG;IACH,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,aAAa,CAAC,oBAAoB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EACvE,YAAY,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GACnD,IAAI;IAIP;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,YAAY,EAAE,qBAAqB,CAAC,EAAE,CAAC,GAAG,IAAI;IA0B1E;;OAEG;IACH,sBAAsB,CACpB,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,oBAAoB,CAAC,GAAG,SAAS;IAIlD;;OAEG;IACH,wBAAwB,CACtB,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS;IAIpD;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAIrE;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIzD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,MAAM,EACjD,YAAY,EAAE,qBAAqB,CAAC,EAAE,CAAC,GACtC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D"}
1
+ {"version":3,"file":"FieldRegistry.d.ts","sourceRoot":"","sources":["../src/FieldRegistry.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,EAAE,SAAS,SAAS,GAAG,SAAS;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;CACzB;AAYD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EAC7D,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAChD,MAAM,GAAG,YAAY,CAAC;AAE3B,gFAAgF;AAChF,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,aAAa,CAAC;AAElB;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB,CAAC,EAAE,SAAS,SAAS,GAAG,SAAS;IACrE,IAAI,EAAE,EAAE,CAAC;IACT,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,aAAa,CACjC,oBAAoB,CAAC,WAAW,EAAE,EAAE,CAAC,CACtC,CAAC;IACF,qBAAqB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;GAGG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAG9B;IACJ,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IAEJ;;;OAGG;IACH,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,aAAa,CAAC,oBAAoB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EACvE,YAAY,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GACnD,IAAI;IAIP;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,SAAS,EAAE,YAAY,EAAE,qBAAqB,CAAC,EAAE,CAAC,GAAG,IAAI;IA4B7E;;OAEG;IACH,sBAAsB,CACpB,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,oBAAoB,CAAC,GAAG,SAAS;IAIlD;;OAEG;IACH,wBAAwB,CACtB,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS;IAIpD;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAIrE;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIzD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,SAAS,EACpD,YAAY,EAAE,qBAAqB,CAAC,EAAE,CAAC,GACtC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -1 +1 @@
1
- "use client";class c{components=new Map;displayFormatters=new Map;filterMetadata=new Map;registerComponent(e,t,n){this.components.set(e,{controlled:t,uncontrolled:n})}register(e){const{type:t,controlledComponent:n,uncontrolledComponent:p,displayFormatter:l,filterable:i,filterType:a}=e;this.components.set(t,{controlled:n,uncontrolled:p}),l&&this.displayFormatters.set(t,l),(i!==void 0||a!==void 0)&&this.filterMetadata.set(t,{filterable:i??!1,filterType:a})}getControlledComponent(e){return this.components.get(e)?.controlled}getUncontrolledComponent(e){return this.components.get(e)?.uncontrolled}getDisplayFormatter(e){return this.displayFormatters.get(e)}getFilterType(e){return this.filterMetadata.get(e)?.filterType}isFilterable(e){return this.filterMetadata.get(e)?.filterable??!1}has(e){return this.components.has(e)}getRegisteredTypes(){return Array.from(this.components.keys())}clear(){this.components.clear(),this.displayFormatters.clear(),this.filterMetadata.clear()}}let o=null;function s(){return o||(o=new c),o}function d(r){s().register(r)}function m(r){return s().has(r)}export{s as getFieldRegistry,m as isFieldTypeRegistered,d as registerFieldType};
1
+ "use client";class d{components=new Map;displayFormatters=new Map;filterMetadata=new Map;registerComponent(e,t,n){this.components.set(e,{controlled:t,uncontrolled:n})}register(e){const{type:t,controlledComponent:n,uncontrolledComponent:i,displayFormatter:o,filterable:l,filterType:a}=e;(n||i)&&this.components.set(t,{controlled:n,uncontrolled:i}),o&&this.displayFormatters.set(t,o),(l!==void 0||a!==void 0)&&this.filterMetadata.set(t,{filterable:l??!1,filterType:a})}getControlledComponent(e){return this.components.get(e)?.controlled}getUncontrolledComponent(e){return this.components.get(e)?.uncontrolled}getDisplayFormatter(e){return this.displayFormatters.get(e)}getFilterType(e){return this.filterMetadata.get(e)?.filterType}isFilterable(e){return this.filterMetadata.get(e)?.filterable??!1}has(e){return this.components.has(e)}getRegisteredTypes(){return Array.from(this.components.keys())}clear(){this.components.clear(),this.displayFormatters.clear(),this.filterMetadata.clear()}}let s=null;function p(){return s||(s=new d),s}function c(r){p().register(r)}function f(r){return p().has(r)}export{p as getFieldRegistry,f as isFieldTypeRegistered,c as registerFieldType};
@@ -1 +1 @@
1
- import{getProvider as u,wrapCrudError as o,validateWithSchema as c}from"@donotdev/core";import{LIST_SCHEMA_TYPE as l}from"@donotdev/core";class h{serverSideOnly=!0;getCallable(){return u("callable")}async getCallableFn(a){const t=this.getCallable();return async i=>({data:await t.call(a,i)})}async get(a,t,i){const n=`get_${a}`,s=await this.getCallableFn(n);try{const e=(await s({id:t})).data;return i?c(i,e,"FunctionsAdapter.get"):e}catch(e){throw o(e,"FunctionsAdapter","get",a,t)}}async set(a,t,i,n){const s=c(n,i,"FunctionsAdapter.set"),e=`update_${a}`,d=await this.getCallableFn(e);try{await d({id:t,payload:s})}catch(r){throw o(r,"FunctionsAdapter","set",a,t)}}async update(a,t,i){const n=`update_${a}`,s=await this.getCallableFn(n);try{await s({id:t,payload:i})}catch(e){throw o(e,"FunctionsAdapter","update",a,t)}}async delete(a,t){const i=`delete_${a}`,n=await this.getCallableFn(i);try{await n({id:t})}catch(s){throw o(s,"FunctionsAdapter","delete",a,t)}}async add(a,t,i){const n=c(i,t,"FunctionsAdapter.add"),s=`create_${a}`,e=await this.getCallableFn(s);try{const d=await e({payload:n});if(!d.data)throw o(new Error("Create function returned no data"),"FunctionsAdapter","add",a);return{id:d.data.id,data:d.data}}catch(d){throw o(d,"FunctionsAdapter","add",a)}}async query(a,t,i,n=l.LIST){const s=n===l.LIST_CARD?`listCard_${a}`:`list_${a}`,e={};t.where&&(e.where=t.where.map(r=>[r.field,r.operator,r.value])),t.orderBy&&(e.orderBy=t.orderBy.map(r=>[r.field,r.direction||"asc"])),t.limit&&(e.limit=t.limit),t.startAfter&&(e.startAfterId=t.startAfter);const d=await this.getCallableFn(s);try{const r=await d(e);if(!r.data)throw o(new Error("Query function returned no data"),"FunctionsAdapter","query",a);return{items:r.data.items,total:r.data.count,hasMore:r.data.hasMore,lastVisible:r.data.lastVisible}}catch(r){throw o(r,"FunctionsAdapter","query",a)}}subscribe(){return()=>{}}subscribeToCollection(){return()=>{}}}export{h as FunctionsAdapter};
1
+ import{getProvider as l,wrapCrudError as o,validateWithSchema as c}from"@donotdev/core";import{LIST_SCHEMA_TYPE as u}from"@donotdev/core";class h{serverSideOnly=!0;getCallable(){return l("callable")}async getCallableFn(a){const t=this.getCallable();return async n=>({data:await t.call(a,n)})}async get(a,t,n){const d=`get_${a}`,i=await this.getCallableFn(d);try{const s=(await i({id:t})).data;return n?c(n,s,"FunctionsAdapter.get"):s}catch(r){throw o(r,"FunctionsAdapter","get",a,t)}}async set(a,t,n,d){const i=c(d,n,"FunctionsAdapter.set"),r=`update_${a}`,s=await this.getCallableFn(r);try{await s({id:t,payload:i})}catch(e){throw o(e,"FunctionsAdapter","set",a,t)}}async update(a,t,n){const d=`update_${a}`,i=await this.getCallableFn(d);try{await i({id:t,payload:n})}catch(r){throw o(r,"FunctionsAdapter","update",a,t)}}async delete(a,t){const n=`delete_${a}`,d=await this.getCallableFn(n);try{await d({id:t})}catch(i){throw o(i,"FunctionsAdapter","delete",a,t)}}async add(a,t,n){const d=c(n,t,"FunctionsAdapter.add"),i=`create_${a}`,r=await this.getCallableFn(i);try{const s=await r({payload:d});if(!s.data)throw o(new Error("Create function returned no data"),"FunctionsAdapter","add",a);return{id:s.data.id,data:s.data}}catch(s){throw o(s,"FunctionsAdapter","add",a)}}async query(a,t,n,d=u.LIST){const i=d===u.LIST_CARD?`listCard_${a}`:`list_${a}`,r={};t.where&&(r.where=t.where.map(e=>[e.field,e.operator,e.value])),t.orderBy&&(r.orderBy=t.orderBy.map(e=>[e.field,e.direction||"asc"])),t.limit&&(r.limit=t.limit),t.startAfter&&(r.startAfterId=t.startAfter);const s=await this.getCallableFn(i);try{const e=await s(r);if(!e.data)throw o(new Error("Query function returned no data"),"FunctionsAdapter","query",a);return{items:e.data.items,total:e.data.count,hasMore:e.data.hasMore,lastVisible:e.data.lastVisible}}catch(e){throw o(e,"FunctionsAdapter","query",a)}}subscribe(){return()=>{}}subscribeToCollection(){return()=>{}}}export{h as FunctionsAdapter};
@@ -1 +1 @@
1
- "use client";import{jsx as d}from"react/jsx-runtime";import{ActionButton as n}from"@donotdev/components";import{useCrudStore as a}from"../CrudStore";function c({requiresAuth:r=!0,user:e,disabled:t=!1,children:s,...i}){const o=a(u=>!!u.crudService);return d(n,{...i,disabled:t||!o||r&&!e,children:s})}var l=c;export{l as default};
1
+ "use client";import{jsx as n}from"react/jsx-runtime";import{ActionButton as d}from"@donotdev/components";import{useCrudStore as l}from"../CrudStore";function a({requiresAuth:t=!0,user:e,disabled:r=!1,children:i,...o}){const s=l(u=>!!u.crudService);return n(d,{...o,disabled:r||!s||t&&!e,children:i})}var p=a;export{p as default};
@@ -3,6 +3,6 @@ import type { CrudCardProps } from '@donotdev/core';
3
3
  * CrudCard — Presentational card from entity + item + field slots.
4
4
  * No routing: use onClick for interaction. Parent wraps with Link if needed.
5
5
  */
6
- export declare function CrudCard({ item, entity, onClick, titleFields: titleFieldsProp, subtitleFields: subtitleFieldsProp, contentFields: contentFieldsProp, footerFields: footerFieldsProp, showDelete, renderActions, elevated, className, }: Omit<CrudCardProps, 'detailHref'>): import("react/jsx-runtime").JSX.Element;
6
+ export declare function CrudCard({ item, entity, onClick, titleFields: titleFieldsProp, subtitleFields: subtitleFieldsProp, contentFields: contentFieldsProp, footerFields: footerFieldsProp, showDelete, renderActions, className, }: CrudCardProps): import("react/jsx-runtime").JSX.Element;
7
7
  export default CrudCard;
8
8
  //# sourceMappingURL=CrudCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CrudCard.d.ts","sourceRoot":"","sources":["../../src/components/CrudCard.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,gBAAgB,CAAC;AA4C7E;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,MAAM,EACN,OAAO,EACP,WAAW,EAAE,eAAe,EAC5B,cAAc,EAAE,kBAAkB,EAClC,aAAa,EAAE,iBAAiB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,UAAkB,EAClB,aAAa,EACb,QAAe,EACf,SAAS,GACV,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,2CAqMnC;AAED,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"CrudCard.d.ts","sourceRoot":"","sources":["../../src/components/CrudCard.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,gBAAgB,CAAC;AA4C7E;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,MAAM,EACN,OAAO,EACP,WAAW,EAAE,eAAe,EAC5B,cAAc,EAAE,kBAAkB,EAClC,aAAa,EAAE,iBAAiB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,UAAkB,EAClB,aAAa,EACb,SAAS,GACV,EAAE,aAAa,2CAqMf;AAED,eAAe,QAAQ,CAAC"}
@@ -1 +1 @@
1
- import{jsx as o,jsxs as T}from"react/jsx-runtime";import{Trash2 as G}from"lucide-react";import{useMemo as g}from"react";import{Card as H,Stack as V,Text as B,ActionButton as J}from"@donotdev/components";import{useTranslation as I,getListCardFieldNames as K}from"@donotdev/core";import{formatValue as h}from"./DisplayFieldRenderer";import{DisplayThumbnail as N}from"./DisplayThumbnail";import{translateFieldLabel as O}from"../forms/utils/translateFieldLabel";import{useCrud as Q}from"../useCrud";function d(e){return e==="image"||e==="images"}function U(e){return g(()=>{const t=e.listCardFields;if(t&&!Array.isArray(t)){const s=t;return{titleFields:s.title??[],subtitleFields:s.subtitle??[],contentFields:s.content??[],footerFields:s.footer??[]}}const c=K(e),f=c.filter(s=>!d(e.fields[s]?.type)),v=c.filter(s=>d(e.fields[s]?.type)),C=f.length>0?[f[0]]:[],b=[...f.slice(1,4),...v];return{titleFields:C,subtitleFields:[],contentFields:b,footerFields:[]}},[e])}function L({item:e,entity:t,onClick:c,titleFields:f,subtitleFields:v,contentFields:C,footerFields:b,showDelete:s=!1,renderActions:j,elevated:R=!0,className:z}){const{t:a}=I([t.namespace,"crud"]),{t:p}=I("crud"),y=U(t),x=f??y.titleFields,S=v??y.subtitleFields,A=C??y.contentFields,m=b??y.footerFields,D=g(()=>{if(!x?.length)return e.id??"";const r=x.filter(i=>typeof i=="string").filter(i=>!d(t.fields[i]?.type)).map(i=>{const n=t.fields[i],F=e[i],u=n?h(F,n,a,{compact:!0,asString:!0}):F;return typeof u=="string"?u:String(u??"")}).filter(Boolean),l=!Array.isArray(t.listCardFields)&&t.listCardFields?.titleSeparator!=null?t.listCardFields.titleSeparator:" ";return r.join(l)||String(e.id??"")},[e,t.fields,x,t.listCardFields,a]),M=g(()=>S?.length&&S.filter(r=>typeof r=="string").filter(r=>!d(t.fields[r]?.type)).map(r=>{const l=t.fields[r],i=e[r],n=l?h(i,l,a,{compact:!0,asString:!0}):i;return typeof n=="string"?n:String(n??"")}).filter(Boolean).join(" ")||void 0,[e,t.fields,S,a]),P=g(()=>{if(!A?.length)return null;const r=A.map(l=>{const i=t.fields[l];if(!i)return null;if(d(i.type)){const n=e[l];return n==null?null:o(N,{pictures:n,alt:String(D),aspectRatio:"16/9"},l)}return T("div",{children:[o(B,{level:"small",variant:"muted",children:O(l,i,a)}),o(B,{children:h(e[l],i,a,{compact:!0})})]},l)}).filter(Boolean);return r.length>0?o(V,{direction:"column",gap:"tight",children:r}):null},[e,t.fields,A,D,a]),q=g(()=>{if(!m?.length)return;if(m.some(l=>d(t.fields[l]?.type))){const l=m.map(i=>{const n=t.fields[i];if(!n)return null;if(d(n.type)){const u=e[i];return u==null?null:o(N,{pictures:u,alt:"",aspectRatio:"1"},i)}const F=h(e[i],n,a,{compact:!0});return o("span",{children:F},i)});return o(V,{direction:"row",gap:"tight",align:"center",children:l.filter(Boolean)})}const r=m.map(l=>{const i=t.fields[l];return i?h(e[l],i,a,{compact:!0}):e[l]});return o(B,{level:"small",children:r.join(" \xB7 ")})},[e,t.fields,m,a]),E=Q(t).delete,k=o(H,{title:String(D??""),subtitle:M,content:P??void 0,footer:q,clickable:!!c,onClick:c?()=>c(e.id):void 0,elevated:R,className:z}),w=j||s?T("div",{style:{position:"absolute",top:"var(--gap-sm)",right:"var(--gap-sm)",zIndex:10,display:"flex",alignItems:"flex-start",gap:"var(--gap-xs)"},onClick:r=>r.stopPropagation(),onMouseDown:r=>r.stopPropagation(),children:[j,s&&o(J,{action:async()=>{await E(e.id)},confirmText:p("delete.confirm",{defaultValue:"Are you sure you want to delete this item?"}),confirmTitle:p("delete.title",{defaultValue:"Delete Item"}),loadingText:p("delete.loading",{defaultValue:"Deleting..."}),variant:"destructive",icon:G,"aria-label":p("delete",{defaultValue:"Delete"}),children:p("delete",{defaultValue:"Delete"})})]}):null;return w?T("div",{style:{position:"relative",height:"100%"},children:[k,w]}):k}var W=L;export{L as CrudCard,W as default};
1
+ import{jsx as i,jsxs as A}from"react/jsx-runtime";import{Trash2 as E}from"lucide-react";import{useMemo as F}from"react";import{Card as G,Stack as L,Text as B,ActionButton as H}from"@donotdev/components";import{useTranslation as R,getListCardFieldNames as J}from"@donotdev/core";import{formatValue as v}from"./DisplayFieldRenderer";import{DisplayThumbnail as y}from"./DisplayThumbnail";import{translateFieldLabel as K}from"../forms/utils/translateFieldLabel";import{useCrud as O}from"../useCrud";function u(t){return t==="image"||t==="images"}function Q(t){return F(()=>{const e=t.listCardFields;if(e&&!Array.isArray(e)){const o=e;return{titleFields:o.title??[],subtitleFields:o.subtitle??[],contentFields:o.content??[],footerFields:o.footer??[]}}const p=J(t),g=p.filter(o=>!u(t.fields[o]?.type)),x=p.filter(o=>u(t.fields[o]?.type)),C=g.length>0?[g[0]]:[],S=[...g.slice(1,4),...x];return{titleFields:C,subtitleFields:[],contentFields:S,footerFields:[]}},[t])}function U({item:t,entity:e,onClick:p,titleFields:g,subtitleFields:x,contentFields:C,footerFields:S,showDelete:o=!1,renderActions:D,className:M}){const{t:n}=R([e.namespace,"crud"]),{t:m}=R("crud"),b=Q(e),T=g??b.titleFields,I=x??b.subtitleFields,j=C??b.contentFields,h=S??b.footerFields,V=F(()=>{if(!T?.length)return t.id??"";const c=T.filter(l=>typeof l=="string").filter(l=>!u(e.fields[l]?.type)).map(l=>{const s=e.fields[l],a=t[l],f=s?v(a,s,n,{compact:!0,asString:!0}):a;return typeof f=="string"?f:String(f??"")}).filter(Boolean),r=!Array.isArray(e.listCardFields)&&e.listCardFields?.titleSeparator!=null?e.listCardFields.titleSeparator:" ";return c.join(r)||String(t.id??"")},[t,e.fields,T,e.listCardFields,n]),P=F(()=>I?.length&&I.filter(r=>typeof r=="string").filter(r=>!u(e.fields[r]?.type)).map(r=>{const l=e.fields[r],s=t[r],a=l?v(s,l,n,{compact:!0,asString:!0}):s;return typeof a=="string"?a:String(a??"")}).filter(Boolean).join(" ")||void 0,[t,e.fields,I,n]),_=F(()=>{if(!j?.length)return null;const c=j.map(r=>{const l=e.fields[r];if(!l)return null;if(u(l.type)){const s=t[r];return s==null?null:i(y,{pictures:s,alt:String(V),aspectRatio:"16/9"},r)}return A("div",{children:[i(B,{level:"small",variant:"muted",children:K(r,l,n)}),i(B,{children:v(t[r],l,n,{compact:!0})})]},r)}).filter(Boolean);return c.length>0?i(L,{direction:"column",gap:"tight",children:c}):null},[t,e.fields,j,V,n]),z=F(()=>{if(!h?.length)return;if(h.some(r=>u(e.fields[r]?.type))){const r=h.map(l=>{const s=e.fields[l];if(!s)return null;if(u(s.type)){const f=t[l];return f==null?null:i(y,{pictures:f,alt:"",aspectRatio:"1"},l)}const a=v(t[l],s,n,{compact:!0});return i("span",{children:a},l)});return i(L,{direction:"row",gap:"tight",align:"center",children:r.filter(Boolean)})}const c=h.map(r=>{const l=e.fields[r];return l?v(t[r],l,n,{compact:!0}):t[r]});return i(B,{level:"small",children:c.join(" \xB7 ")})},[t,e.fields,h,n]),q=O(e).delete,w=i(G,{title:String(V??""),subtitle:P,content:_??void 0,footer:z,clickable:!0,elevated:!0,onClick:p?()=>p(t.id):void 0,className:M}),k=D||o?A("div",{style:{position:"absolute",top:"var(--gap-sm)",right:"var(--gap-sm)",zIndex:10,display:"flex",alignItems:"flex-start",gap:"var(--gap-xs)"},onClick:d=>d.stopPropagation(),onMouseDown:d=>d.stopPropagation(),children:[D,o&&i(H,{action:async()=>{await q(t.id)},confirmText:m("delete.confirm",{defaultValue:"Are you sure you want to delete this item?"}),confirmTitle:m("delete.title",{defaultValue:"Delete Item"}),loadingText:m("delete.loading",{defaultValue:"Deleting..."}),variant:"destructive",icon:E,"aria-label":m("delete",{defaultValue:"Delete"}),children:m("delete",{defaultValue:"Delete"})})]}):null;return k?A("div",{style:{position:"relative",height:"100%"},children:[w,k]}):w}var lt=U;export{U as CrudCard,lt as default};
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as b,Fragment as ct}from"react/jsx-runtime";import{X as ut}from"lucide-react";import{useState as k,useMemo as ht}from"react";import{Button as S,Calendar as St,FloatingLabel as Dt,Sheet as T,Text as ft}from"@donotdev/components";import{formatDate as xt}from"@donotdev/core";function $t({label:D,fieldType:vt,value:l,onChange:f,tCrud:i,locale:O="en"}){const[M,o]=k(!1),[F,x]=k(null),N=ht(()=>l?typeof l=="object"&&l!==null&&"min"in l?{min:l.min||"",max:l.max||""}:{min:"",max:""}:{min:"",max:""},[l]),C=t=>{if(!t)return"";try{const n=new Date(t+"T00:00:00");return xt(n,O)}catch{return t}},W=()=>{const t=new Date;t.setHours(0,0,0,0);const n=t.getFullYear(),d=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),g=`${n}-${d}-${r}`,s=new Date(t);s.setDate(s.getDate()-1);const v=s.getFullYear(),$=String(s.getMonth()+1).padStart(2,"0"),z=String(s.getDate()).padStart(2,"0"),B=`${v}-${$}-${z}`,m=new Date(t);m.setDate(m.getDate()+1);const H=m.getFullYear(),L=String(m.getMonth()+1).padStart(2,"0"),X=String(m.getDate()).padStart(2,"0"),q=`${H}-${L}-${X}`,p=new Date(t);p.setDate(p.getDate()-7);const A=p.getFullYear(),G=String(p.getMonth()+1).padStart(2,"0"),I=String(p.getDate()).padStart(2,"0"),J=`${A}-${G}-${I}`,c=new Date(t);c.setDate(c.getDate()-30);const K=c.getFullYear(),P=String(c.getMonth()+1).padStart(2,"0"),Q=String(c.getDate()).padStart(2,"0"),R=`${K}-${P}-${Q}`,u=new Date(t);u.setDate(u.getDate()+7);const U=u.getFullYear(),Z=String(u.getMonth()+1).padStart(2,"0"),_=String(u.getDate()).padStart(2,"0"),tt=`${U}-${Z}-${_}`,h=new Date(t);h.setDate(h.getDate()+30);const et=h.getFullYear(),at=String(h.getMonth()+1).padStart(2,"0"),nt=String(h.getDate()).padStart(2,"0"),rt=`${et}-${at}-${nt}`,y=new Date(t.getFullYear(),t.getMonth(),1),lt=y.getFullYear(),it=String(y.getMonth()+1).padStart(2,"0"),ot=String(y.getDate()).padStart(2,"0"),st=`${lt}-${it}-${ot}`,w=new Date(t.getFullYear(),t.getMonth()+1,0),dt=w.getFullYear(),gt=String(w.getMonth()+1).padStart(2,"0"),mt=String(w.getDate()).padStart(2,"0"),pt=`${dt}-${gt}-${mt}`;return{today:g,yesterday:B,tomorrow:q,last7Days:J,last30Days:R,next7Days:tt,next30Days:rt,thisMonthStart:st,thisMonthEnd:pt}},a=N,j=W(),E=!!(a?.min||a?.max),Y=t=>{const n=t==="start",d=n?a?.min:a?.max;return e("div",{style:{padding:"var(--gap-md)"},children:b("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-md)"},children:[e("div",{style:{display:"flex",flexWrap:"wrap",gap:"var(--gap-tight)"},children:(n?["today","yesterday","last7Days","last30Days","thisMonthStart"]:["today","tomorrow","next7Days","next30Days","thisMonthEnd"]).map(r=>{const g=j[r];return e(S,{variant:"outline",onClick:()=>{f({min:n?g:a?.min||"",max:n?a?.max||"":g}),o(!1)},children:i(`filter.${r}`,{defaultValue:r})},r)})}),e(St,{selected:d?new Date(d+"T00:00:00"):void 0,mode:"single",onSelect:r=>{if(!r)return;const g=r.getFullYear(),s=String(r.getMonth()+1).padStart(2,"0"),v=String(r.getDate()).padStart(2,"0"),$=`${g}-${s}-${v}`;f({min:n?$:a?.min||"",max:n?a?.max||"":$}),o(!1)},defaultMonth:d?new Date(d+"T00:00:00"):new Date}),e(S,{variant:"ghost",display:"compact",onClick:()=>{f({min:n?"":a?.min||"",max:n&&a?.max||""}),o(!1)},children:i("filter.clear",{defaultValue:"Clear"})})]})})},V=b(ct,{children:[e(T,{trigger:e(S,{variant:"ghost",onClick:()=>{x("start"),o(!0)},style:{minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a?.min?C(a.min):i("filter.min",{defaultValue:"Min"})}),title:`${D} - ${i("filter.min",{defaultValue:"Min"})}`,open:M&&F==="start",onOpenChange:t=>{o(t),t||x(null)},children:Y("start")}),e(ft,{level:"small",variant:"muted",className:"dndev-range-input-separator",children:"\u2013"}),e(T,{trigger:e(S,{variant:"ghost",onClick:()=>{x("end"),o(!0)},style:{minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a?.max?C(a.max):i("filter.max",{defaultValue:"Max"})}),title:`${D} - ${i("filter.max",{defaultValue:"Max"})}`,open:M&&F==="end",onOpenChange:t=>{o(t),t||x(null)},children:Y("end")}),e(S,{variant:"ghost",display:"compact",icon:e(ut,{size:16}),onClick:()=>{f(void 0)},disabled:!E,"aria-label":i("filter.clear",{defaultValue:"Clear"})})]});return D?e(Dt,{label:D,children:e("div",{className:"dndev-range-input",children:V})}):e("div",{className:"dndev-range-input",children:V})}export{$t as DateFilter};
1
+ "use client";import{jsx as e,jsxs as k,Fragment as ht}from"react/jsx-runtime";import{X as Dt}from"lucide-react";import{useState as T,useMemo as pt}from"react";import{Button as S,Calendar as St,FloatingLabel as yt,Sheet as E,Text as ut}from"@donotdev/components";import{formatDate as ft}from"@donotdev/core";function Ft({label:y,fieldType:xt,value:s,onChange:u,tCrud:o,locale:N="en"}){const[Y,i]=T(!1),[v,f]=T(null),O=pt(()=>s?typeof s=="object"&&s!==null&&"min"in s?{min:s.min||"",max:s.max||""}:{min:"",max:""}:{min:"",max:""},[s]),F=t=>{if(!t)return"";try{const n=new Date(t+"T00:00:00");return ft(n,N)}catch{return t}},W=()=>{const t=new Date;t.setHours(0,0,0,0);const n=t.getFullYear(),c=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),d=`${n}-${c}-${r}`,l=new Date(t);l.setDate(l.getDate()-1);const M=l.getFullYear(),x=String(l.getMonth()+1).padStart(2,"0"),C=String(l.getDate()).padStart(2,"0"),R=`${M}-${x}-${C}`,g=new Date(t);g.setDate(g.getDate()+1);const z=g.getFullYear(),A=String(g.getMonth()+1).padStart(2,"0"),B=String(g.getDate()).padStart(2,"0"),H=`${z}-${A}-${B}`,m=new Date(t);m.setDate(m.getDate()-7);const L=m.getFullYear(),P=String(m.getMonth()+1).padStart(2,"0"),X=String(m.getDate()).padStart(2,"0"),q=`${L}-${P}-${X}`,h=new Date(t);h.setDate(h.getDate()-30);const G=h.getFullYear(),I=String(h.getMonth()+1).padStart(2,"0"),J=String(h.getDate()).padStart(2,"0"),K=`${G}-${I}-${J}`,D=new Date(t);D.setDate(D.getDate()+7);const Q=D.getFullYear(),U=String(D.getMonth()+1).padStart(2,"0"),Z=String(D.getDate()).padStart(2,"0"),tt=`${Q}-${U}-${Z}`,p=new Date(t);p.setDate(p.getDate()+30);const et=p.getFullYear(),at=String(p.getMonth()+1).padStart(2,"0"),nt=String(p.getDate()).padStart(2,"0"),rt=`${et}-${at}-${nt}`,$=new Date(t.getFullYear(),t.getMonth(),1),st=$.getFullYear(),ot=String($.getMonth()+1).padStart(2,"0"),it=String($.getDate()).padStart(2,"0"),lt=`${st}-${ot}-${it}`,w=new Date(t.getFullYear(),t.getMonth()+1,0),ct=w.getFullYear(),dt=String(w.getMonth()+1).padStart(2,"0"),gt=String(w.getDate()).padStart(2,"0"),mt=`${ct}-${dt}-${gt}`;return{today:d,yesterday:R,tomorrow:H,last7Days:q,last30Days:K,next7Days:tt,next30Days:rt,thisMonthStart:lt,thisMonthEnd:mt}},a=O,_=W(),b=!!(a?.min||a?.max),V=t=>{const n=t==="start",c=n?a?.min:a?.max;return e("div",{style:{padding:"var(--gap-md)"},children:k("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-md)"},children:[e("div",{style:{display:"flex",flexWrap:"wrap",gap:"var(--gap-tight)"},children:(n?["today","yesterday","last7Days","last30Days","thisMonthStart"]:["today","tomorrow","next7Days","next30Days","thisMonthEnd"]).map(r=>{const d=_[r];return e(S,{variant:"outline",onClick:()=>{u({min:n?d:a?.min||"",max:n?a?.max||"":d}),i(!1)},children:o(`filter.${r}`,{defaultValue:r})},r)})}),e(St,{selected:c?new Date(c+"T00:00:00"):void 0,mode:"single",onSelect:r=>{if(!r)return;const d=r.getFullYear(),l=String(r.getMonth()+1).padStart(2,"0"),M=String(r.getDate()).padStart(2,"0"),x=`${d}-${l}-${M}`;u({min:n?x:a?.min||"",max:n?a?.max||"":x}),i(!1)},defaultMonth:c?new Date(c+"T00:00:00"):new Date}),e(S,{variant:"ghost",display:"compact",onClick:()=>{u({min:n?"":a?.min||"",max:n&&a?.max||""}),i(!1)},children:o("filter.clear",{defaultValue:"Clear"})})]})})},j=k(ht,{children:[e(E,{trigger:e(S,{variant:"ghost",onClick:()=>{f("start"),i(!0)},style:{minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a?.min?F(a.min):o("filter.min",{defaultValue:"Min"})}),title:`${y} - ${o("filter.min",{defaultValue:"Min"})}`,open:Y&&v==="start",onOpenChange:t=>{i(t),t||f(null)},children:V("start")}),e(ut,{level:"small",variant:"muted",className:"dndev-range-input-separator",children:"\u2013"}),e(E,{trigger:e(S,{variant:"ghost",onClick:()=>{f("end"),i(!0)},style:{minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a?.max?F(a.max):o("filter.max",{defaultValue:"Max"})}),title:`${y} - ${o("filter.max",{defaultValue:"Max"})}`,open:Y&&v==="end",onOpenChange:t=>{i(t),t||f(null)},children:V("end")}),e(S,{variant:"ghost",display:"compact",icon:e(Dt,{size:16}),onClick:()=>{u(void 0)},disabled:!b,"aria-label":o("filter.clear",{defaultValue:"Clear"})})]});return y?e(yt,{label:y,children:e("div",{className:"dndev-range-input",children:j})}):e("div",{className:"dndev-range-input",children:j})}export{Ft as DateFilter};
@@ -1 +1 @@
1
- {"version":3,"file":"DisplayFieldRenderer.d.ts","sourceRoot":"","sources":["../../src/components/DisplayFieldRenderer.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,WAAW,yBAAyB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IACxE,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,0BAA0B;IAC1B,KAAK,EAAE,GAAG,CAAC;IACX,2BAA2B;IAC3B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;CAC3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,EACzD,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,GAAG,YAAY,CA4DvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,EACpE,IAAI,EACJ,MAAM,EACN,KAAK,EACL,CAAC,GACF,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,YAAY,CAyC7C;AAED,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"DisplayFieldRenderer.d.ts","sourceRoot":"","sources":["../../src/components/DisplayFieldRenderer.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,WAAW,yBAAyB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IACxE,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,0BAA0B;IAC1B,KAAK,EAAE,GAAG,CAAC;IACX,2BAA2B;IAC3B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;CAC3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,EACzD,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,GAAG,YAAY,CA+EvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,EACpE,IAAI,EACJ,MAAM,EACN,KAAK,EACL,CAAC,GACF,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,YAAY,CAyC7C;AAED,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- "use client";import{jsx as r,jsxs as d}from"react/jsx-runtime";import{Text as o,Stack as g}from"@donotdev/components";import{handleError as m}from"@donotdev/core";import{getDisplayFormatter as u}from"../fieldTypeRegistry";import{translateFieldLabel as y}from"../forms/utils";function p(t,e,l,n){const i=n?.compact??!1,a=n?.asString??!1;if(t==null||t==="")return a?"\u2014":i?r("span",{style:{color:"var(--muted-foreground)"},children:"\u2014"}):r(o,{variant:"muted",children:"\u2014"});const s=u(e.type);if(s)try{return s(t,e,l,n)}catch(c){return m(c,{userMessage:`Error formatting field "${e.label||e.name}"`,context:{fieldType:e.type,fieldName:e.label||"unknown",operation:"display_format"},severity:"warning"}),a?String(t):i?r("span",{style:{color:"var(--muted-foreground)"},children:String(t)}):r(o,{variant:"muted",children:String(t)})}return m(new Error(`Display formatter not registered for field type: ${e.type}`),{userMessage:`Field type "${e.type}" is missing display formatter`,context:{fieldType:e.type,fieldName:e.label||"unknown",operation:"display_format",fix:"Add displayFormatter to registerBuiltinFieldType() in registerBuiltinFieldTypes.tsx"},severity:"warning"}),a?String(t):i?r("span",{style:{color:"var(--muted-foreground)"},children:String(t)}):r(o,{variant:"muted",children:String(t)})}function f({name:t,config:e,value:l,t:n}){const i=p(l,e,n,{compact:!1}),a=y(t,e,n);return d(g,{direction:"row",align:"baseline",style:{marginBottom:"var(--gap-sm)",padding:"var(--gap-sm)",minHeight:"38px",alignItems:"center"},children:[d(o,{variant:"muted",style:{fontSize:"var(--font-size-sm)",fontWeight:500,minWidth:"fit-content",flexShrink:0},children:[a,":"]}),r("div",{style:{flex:1,display:"flex",alignItems:"center"},children:typeof i=="string"?r(o,{children:i}):i})]})}var h=f;export{f as DisplayFieldRenderer,h as default,p as formatValue};
1
+ "use client";import{jsx as t,jsxs as y}from"react/jsx-runtime";import{Text as o,Stack as u}from"@donotdev/components";import{handleError as f}from"@donotdev/core";import{getDisplayFormatter as g}from"../fieldTypeRegistry";import{translateFieldLabel as h}from"../forms/utils";function x(r,e,a,i){const n=i?.compact??!1,s=i?.asString??!1;if(r==null||r==="")return s?"\u2014":n?t("span",{style:{color:"var(--muted-foreground)"},children:"\u2014"}):t(o,{variant:"muted",children:"\u2014"});const d=g(e.type),m=e.options?.displayKey;if(m){let l=String(r);if(d)try{const p=d(r,e,a,i);l=typeof p=="string"?p:String(r)}catch{}const c=(Array.isArray(m)?m:[m]).map(p=>p.replace("{{value}}",l));return a(c,{value:l})}if(d)try{return d(r,e,a,i)}catch(l){return f(l,{userMessage:`Error formatting field "${e.label||e.name}"`,context:{fieldType:e.type,fieldName:e.label||"unknown",operation:"display_format"},severity:"warning"}),s?String(r):n?t("span",{style:{color:"var(--muted-foreground)"},children:String(r)}):t(o,{variant:"muted",children:String(r)})}return f(new Error(`Display formatter not registered for field type: ${e.type}`),{userMessage:`Field type "${e.type}" is missing display formatter`,context:{fieldType:e.type,fieldName:e.label||"unknown",operation:"display_format",fix:"Add displayFormatter to registerBuiltinFieldType() in registerBuiltinFieldTypes.tsx"},severity:"warning"}),s?String(r):n?t("span",{style:{color:"var(--muted-foreground)"},children:String(r)}):t(o,{variant:"muted",children:String(r)})}function S({name:r,config:e,value:a,t:i}){const n=x(a,e,i,{compact:!1}),s=h(r,e,i);return y(u,{direction:"row",align:"baseline",style:{marginBottom:"var(--gap-sm)",padding:"var(--gap-sm)",minHeight:"38px",alignItems:"center"},children:[y(o,{variant:"muted",style:{fontSize:"var(--font-size-sm)",fontWeight:500,minWidth:"fit-content",flexShrink:0},children:[s,":"]}),t("div",{style:{flex:1,display:"flex",alignItems:"center"},children:typeof n=="string"?t(o,{children:n}):n})]})}var j=S;export{S as DisplayFieldRenderer,j as default,x as formatValue};
@@ -1 +1 @@
1
- "use client";import{jsx as n}from"react/jsx-runtime";function o(t){if(t==null)return null;if(typeof t=="string")return t||null;const l=Array.isArray(t)&&t.length>0?t[0]:t;if(!l||typeof l!="object")return null;const e=l.thumbUrl??l.fullUrl;return typeof e=="string"?e:null}function r({pictures:t,alt:l="",aspectRatio:e="16/9",className:a,style:s}){const i=o(t);return i?n("div",{className:a,style:{width:"100%",aspectRatio:e,borderRadius:"var(--radius-md)",overflow:"hidden",backgroundColor:"var(--muted)",position:"relative",...s},children:n("img",{src:i,alt:l,loading:"lazy",style:{width:"100%",height:"100%",objectFit:"cover"}})}):null}var u=r;export{r as DisplayThumbnail,u as default};
1
+ "use client";import{jsx as e}from"react/jsx-runtime";function u(r){if(r==null)return null;if(typeof r=="string")return r||null;const l=Array.isArray(r)&&r.length>0?r[0]:r;if(!l||typeof l!="object")return null;const t=l.thumbUrl??l.fullUrl;return typeof t=="string"?t:null}function a({pictures:r,alt:l="",aspectRatio:t="16/9",className:o,style:i}){const n=u(r);return n?e("div",{className:o,style:{width:"100%",aspectRatio:t,borderRadius:"var(--radius-md)",overflow:"hidden",backgroundColor:"var(--muted)",position:"relative",...i},children:e("img",{src:n,alt:l,loading:"lazy",style:{width:"100%",height:"100%",objectFit:"cover"}})}):null}var d=a;export{a as DisplayThumbnail,d as default};
@@ -1 +1 @@
1
- "use client";import{jsx as u,jsxs as _}from"react/jsx-runtime";import{FilterX as Y}from"lucide-react";import{useMemo as V}from"react";import{Button as Z,Combobox as W,Grid as ee,Rating as te,RangeInput as ae,Slider as ie,Stack as le}from"@donotdev/components";import{useTranslation as D,handleError as B}from"@donotdev/core";import{DateFilter as ne}from"./DateFilter";import{getFilterType as $,isFilterable as re}from"../fieldTypeRegistry";import{translateFieldLabel as se,translateLabel as I}from"../forms/utils";import{useCrudFilters as oe}from"../hooks/useCrudFilters";import{useCrudCardList as me}from"../useCrudCardList";import{matchesFilter as de}from"../utils/matchesFilter";import{matchesFilter as ue}from"../utils/matchesFilter";function ce({entity:d,data:O,fieldsToFilter:T,variant:L="inline",cols:P}){const z=L==="sidebar",{t:p,i18n:G}=D("crud"),{t:w}=D([d.namespace,"crud"]),X=G?.language||"en",{data:q}=me(d,{enabled:!O}),f=O??(q?.items||[]),{filters:b,setFilters:A}=oe({collection:d.collection}),g=V(()=>(T&&T.length>0?T:d.listFields||Object.keys(d.fields)).filter(a=>{const t=d.fields[a]?.type||"text";return re(t)}),[T,d.listFields,d.fields]),R=V(()=>{const a={};return g.forEach(t=>{const o=Object.fromEntries(Object.entries(b).filter(([i])=>i!==t));if(Object.keys(o).length===0){a[t]=f;return}a[t]=f.filter(i=>Object.entries(o).every(([m,h])=>{const F=i[m],x=d.fields[m]?.type||"text";return de(F,h,x)}))}),a},[f,b,d.fields,g]),H=V(()=>{const a={};return g.forEach(t=>{const o=d.fields[t];if(!o)return;const i=o.type||"text",m=$(i);if(!m){B(new Error(`Field type "${i}" not registered in field type registry`),{userMessage:`Field type "${i}" is missing from registry`,context:{fieldType:i,fieldName:t,operation:"minmax_computation",fix:"Add to registerBuiltinFieldTypes.ts or registerFieldType()"},severity:"warning"});return}const h=m==="range"&&(i==="date"||i==="datetime-local"||i==="timestamp"||i==="time"||i==="week"||i==="month"||i==="year"),F=m==="range"&&!h,x=i==="price";if(F||x){const n=f.map(l=>l[t]).filter(l=>l!=null&&l!=="").map(l=>x&&typeof l=="object"&&l!==null?Number(l.amount):typeof l=="number"?l:Number(l)).filter(l=>!isNaN(l));n.length>0&&(a[t]={min:Math.min(...n),max:Math.max(...n)})}else if(h){const n=f.map(l=>l[t]).filter(l=>l!=null&&l!=="").map(l=>l instanceof Date?l:new Date(l)).filter(l=>!isNaN(l.getTime()));if(n.length>0){const l=new Date(Math.min(...n.map(C=>C.getTime()))),S=new Date(Math.max(...n.map(C=>C.getTime()))),k=l.toISOString().split("T")[0],v=S.toISOString().split("T")[0];a[t]={min:k||"",max:v||""}}}}),a},[f,d.fields,g]),y=(a,t)=>{const o={...b};if(!t||t==="")delete o[a];else if(Array.isArray(t))o[a]=t;else if(typeof t=="object"&&"min"in t){const i=t.min&&t.min!=="",m=t.max&&t.max!=="";!i&&!m?delete o[a]:o[a]=t}else o[a]=t;A(o)},J=()=>{A({})},M=V(()=>g.length===0?null:g.map(a=>{const t=d.fields[a];if(!t)return null;const o=se(a,t,w),i=t.type||"text",m=$(i);if(!m)return B(new Error(`Field type "${i}" not registered in field type registry`),{userMessage:`Field type "${i}" is missing from registry`,context:{fieldType:i,fieldName:a,operation:"filter_ui_render",fix:"Add to registerBuiltinFieldTypes.ts or registerFieldType()"},severity:"warning"}),null;const h=m==="range"&&(i==="date"||i==="datetime-local"||i==="timestamp"||i==="time"||i==="week"||i==="month"||i==="year"),F=m==="range"&&!h,x=m==="select",n=b[a],l=typeof n=="object"&&n!==null&&"min"in n?n:{min:"",max:""};if(m==="rating"){const r=t.validation?.max??5,s=typeof n=="string"&&n!==""?Number(n):0;return u("div",{style:{gridColumn:"span 2",gridRow:"span 1"},children:u(te,{value:s,max:r,"aria-label":o,onChange:e=>{y(a,e===s?void 0:String(e))}})},a)}if(F){const r=H[a],s=r?.min??0,e=r?.max??100,c=l.min?Number(l.min):s,N=l.max?Number(l.max):e;return _(le,{gap:"tight",style:{gridColumn:"span 2"},children:[u(ae,{type:"number",label:o,minPlaceholder:p("filter.min",{defaultValue:"Min"}),maxPlaceholder:p("filter.max",{defaultValue:"Max"}),minValue:l.min||"",maxValue:l.max||"",actualMin:s,actualMax:e,onChange:(j,U)=>{y(a,{min:j,max:U})},onClear:()=>y(a,void 0)}),u(ie,{value:[c,N],min:s,max:e,step:1,onValueChange:j=>{y(a,{min:String(j[0]),max:String(j[1])})}})]},a)}if(h){const r=i==="week"||i==="month"||i==="year"?i:"date",s=(()=>{if(n){if(typeof n=="object"&&"min"in n){const e=n;return{min:e.min&&e.min.split("T")[0]||"",max:e.max&&e.max.split("T")[0]||""}}if(typeof n=="string"){const e=n.split("T")[0]||"";return{min:e,max:e}}}})();return u("div",{style:{gridColumn:"span 2",gridRow:"span 1"},children:u(ne,{label:o,fieldType:r,value:s,locale:X,onChange:e=>{if(!e){y(a,void 0);return}typeof e=="object"&&"min"in e&&y(a,{min:e.min||"",max:e.max||""})},tCrud:p})},a)}const S=x&&t.validation&&"options"in t.validation&&t.validation?Array.isArray(t.validation.options)?t.validation.options:typeof t.validation.options=="function"?t.validation.options():[]:[],k=R[a]||f,v=new Set,C=m==="address";k.forEach(r=>{const s=r[a];if(s!=null)if(C&&typeof s=="object"&&"formatted_address"in s){const e=s;e.formatted_address&&v.add(String(e.formatted_address))}else v.add(String(s))});const E=[{value:"all",label:p("filter.selectPlaceholder",{defaultValue:"All"})}];if(S.length>0){const r=[],s=[];S.forEach(e=>{const c=typeof e=="string"?e:e.value,N=typeof e=="string"?e:e.label;v.has(c)?r.push({value:c,label:N}):s.push({value:c,label:N})}),r.sort((e,c)=>e.label.localeCompare(c.label)),s.sort((e,c)=>e.label.localeCompare(c.label)),r.forEach(e=>{E.push({value:e.value,label:I(e.label,w),disabled:!1})}),s.forEach(e=>{E.push({value:e.value,label:I(e.label,w),disabled:!0})})}else Array.from(v).sort().slice(0,100).forEach(r=>{E.push({value:r,label:r})});return u("div",{style:{gridColumn:"span 1",gridRow:"span 1"},children:u(W,{label:o,value:typeof n=="string"?n:void 0,onValueChange:r=>{y(a,r==="all"||!r?"":String(r))},options:E,placeholder:p("filter.placeholder",{defaultValue:"Filter..."}),clearable:!0})},a)}),[g,d.fields,f,b,w,p,R]);if(!M||M.length===0)return null;const K=M.filter(Boolean),Q=Object.keys(b).length>0;return _(ee,{cols:P??(z?2:[2,4,4,6]),children:[K,u(Z,{variant:"outline",icon:u(Y,{size:18}),onClick:J,disabled:!Q,style:{gridColumn:"1 / -1",gridRow:"span 1"},children:p("filter.clear",{defaultValue:"Clear Filters"})})]})}export{ce as EntityFilters,ue as matchesFilter};
1
+ "use client";import{jsx as m,jsxs as P}from"react/jsx-runtime";import{FilterX as N}from"lucide-react";import{useMemo as O}from"react";import{Button as ee,Combobox as te,Grid as ne,Rating as ie,RangeInput as re,Slider as se,Stack as le}from"@donotdev/components";import{useTranslation as B,handleError as L}from"@donotdev/core";import{DateFilter as ae}from"./DateFilter";import{getFilterType as $,isFilterable as oe}from"../fieldTypeRegistry";import{translateFieldLabel as ce,translateLabel as I}from"../forms/utils";import{useCrudFilters as de}from"../hooks/useCrudFilters";import{useCrudCardList as me}from"../useCrudCardList";import{matchesFilter as ue}from"../utils/matchesFilter";import{matchesFilter as ke}from"../utils/matchesFilter";function Oe({entity:d,data:R,fieldsToFilter:S,variant:z="inline",cols:G}){const X=z==="sidebar",{t:g,i18n:q}=B("crud"),{t:j}=B([d.namespace,"crud"]),H=q?.language||"en",{data:J}=me(d,{enabled:!R}),f=R??(J?.items||[]),{filters:y,setFilters:k}=de({collection:d.collection}),h=O(()=>(S&&S.length>0?S:d.listFields||Object.keys(d.fields)).filter(t=>{const n=d.fields[t]?.type||"text";return oe(n)}),[S,d.listFields,d.fields]),v=O(()=>{const i={};return h.forEach(t=>{const o=Object.fromEntries(Object.entries(y).filter(([n])=>n!==t));if(Object.keys(o).length===0){i[t]=f;return}i[t]=f.filter(n=>Object.entries(o).every(([c,x])=>{const F=n[c],s=d.fields[c]?.type||"text";return ue(F,x,s)}))}),i},[f,y,d.fields,h]),K=O(()=>{const i={};return h.forEach(t=>{const o=d.fields[t];if(!o)return;const n=o.type||"text",c=$(n);if(!c){L(new Error(`Field type "${n}" not registered in field type registry`),{userMessage:`Field type "${n}" is missing from registry`,context:{fieldType:n,fieldName:t,operation:"minmax_computation",fix:"Add to registerBuiltinFieldTypes.ts or registerFieldType()"},severity:"warning"});return}const x=c==="range"&&(n==="date"||n==="datetime-local"||n==="timestamp"||n==="time"||n==="week"||n==="month"||n==="year"),F=c==="range"&&!x,C=n==="price";if(F||C){const s=f.map(r=>r[t]).filter(r=>r!=null&&r!=="").map(r=>C&&typeof r=="object"&&r!==null?Number(r.amount):typeof r=="number"?r:Number(r)).filter(r=>!isNaN(r));s.length>0&&(i[t]={min:Math.min(...s),max:Math.max(...s)})}else if(x){const s=f.map(r=>r[t]).filter(r=>r!=null&&r!=="").map(r=>r instanceof Date?r:new Date(r)).filter(r=>!isNaN(r.getTime()));if(s.length>0){const r=new Date(Math.min(...s.map(T=>T.getTime()))),p=new Date(Math.max(...s.map(T=>T.getTime()))),_=r.toISOString().split("T")[0],E=p.toISOString().split("T")[0];i[t]={min:_||"",max:E||""}}}}),i},[f,d.fields,h]),b=(i,t)=>{const o={...y};if(!t||t==="")delete o[i];else if(Array.isArray(t))o[i]=t;else if(typeof t=="object"&&"min"in t){const n=t.min&&t.min!=="",c=t.max&&t.max!=="";!n&&!c?delete o[i]:o[i]=t}else o[i]=t;k(o)},Q=()=>{k({})},V=O(()=>h.length===0?null:h.map(i=>{const t=d.fields[i];if(!t)return null;const o=ce(i,t,j),n=t.type||"text",c=$(n);if(!c)return L(new Error(`Field type "${n}" not registered in field type registry`),{userMessage:`Field type "${n}" is missing from registry`,context:{fieldType:n,fieldName:i,operation:"filter_ui_render",fix:"Add to registerBuiltinFieldTypes.ts or registerFieldType()"},severity:"warning"}),null;const x=c==="range"&&(n==="date"||n==="datetime-local"||n==="timestamp"||n==="time"||n==="week"||n==="month"||n==="year"),F=c==="range"&&!x,C=c==="select",s=y[i],p=typeof s=="object"&&s!==null&&"min"in s?s:{min:"",max:""};if(c==="rating"){const l=t.validation?.max??5,a=typeof s=="string"&&s!==""?Number(s):0;return m("div",{style:{gridColumn:"span 2",gridRow:"span 1"},children:m(ie,{value:a,max:l,"aria-label":o,onChange:e=>{b(i,e===a?void 0:String(e))}})},i)}if(F){const l=K[i],a=l?.min??0,e=l?.max??100,u=p.min?Number(p.min):a,A=p.max?Number(p.max):e;return P(le,{gap:"tight",style:{gridColumn:"span 2"},children:[m(re,{type:"number",label:o,minPlaceholder:g("filter.min",{defaultValue:"Min"}),maxPlaceholder:g("filter.max",{defaultValue:"Max"}),minValue:p.min||"",maxValue:p.max||"",actualMin:a,actualMax:e,onChange:(M,Z)=>{b(i,{min:M,max:Z})},onClear:()=>b(i,void 0)}),m(se,{value:[u,A],min:a,max:e,step:1,onValueChange:M=>{b(i,{min:String(M[0]),max:String(M[1])})}})]},i)}if(x){const l=n==="week"||n==="month"||n==="year"?n:"date",a=(()=>{if(s){if(typeof s=="object"&&"min"in s){const e=s;return{min:e.min&&e.min.split("T")[0]||"",max:e.max&&e.max.split("T")[0]||""}}if(typeof s=="string"){const e=s.split("T")[0]||"";return{min:e,max:e}}}})();return m("div",{style:{gridColumn:"span 2",gridRow:"span 1"},children:m(ae,{label:o,fieldType:l,value:a,locale:H,onChange:e=>{if(!e){b(i,void 0);return}typeof e=="object"&&"min"in e&&b(i,{min:e.min||"",max:e.max||""})},tCrud:g})},i)}const E=C&&t.validation&&"options"in t.validation&&t.validation?Array.isArray(t.validation.options)?t.validation.options:typeof t.validation.options=="function"?t.validation.options():[]:[],T=v[i]||f,D=new Set,Y=c==="address";T.forEach(l=>{const a=l[i];if(a!=null)if(Y&&typeof a=="object"&&"formatted_address"in a){const e=a;e.formatted_address&&D.add(String(e.formatted_address))}else D.add(String(a))});const w=[{value:"all",label:g("filter.selectPlaceholder",{defaultValue:"All"})}];if(E.length>0){const l=[],a=[];E.forEach(e=>{const u=typeof e=="string"?e:e.value,A=typeof e=="string"?e:e.label;D.has(u)?l.push({value:u,label:A}):a.push({value:u,label:A})}),l.sort((e,u)=>e.label.localeCompare(u.label)),a.sort((e,u)=>e.label.localeCompare(u.label)),l.forEach(e=>{w.push({value:e.value,label:I(e.label,j),disabled:!1})}),a.forEach(e=>{w.push({value:e.value,label:I(e.label,j),disabled:!0})})}else Array.from(D).sort().slice(0,100).forEach(l=>{w.push({value:l,label:l})});return m("div",{style:{gridColumn:"span 1",gridRow:"span 1"},children:m(te,{label:o,value:typeof s=="string"?s:void 0,onValueChange:l=>{b(i,l==="all"||!l?"":String(l))},options:w,placeholder:g("filter.placeholder",{defaultValue:"Filter..."}),clearable:!0})},i)}),[h,d.fields,f,y,j,g,v]);if(!V||V.length===0)return null;const U=V.filter(Boolean),W=Object.keys(y).length>0;return P(ne,{cols:G??(X?2:[2,4,4,6]),children:[U,m(ee,{variant:"outline",icon:m(N,{size:18}),onClick:Q,disabled:!W,style:{gridColumn:"1 / -1",gridRow:"span 1"},children:g("filter.clear",{defaultValue:"Clear Filters"})})]})}export{Oe as EntityFilters,ke as matchesFilter};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{handleError as C}from"@donotdev/core";import{getFieldRegistry as F}from"../FieldRegistry";import{ControlledTextField as T}from"./controlled";import{TextFieldComponent as w}from"./form/fields";const v=F();function h({name:o,config:e,t:r,...n}){const p=l=>i=>{try{l(i)}catch(a){C(a,{userMessage:`Error updating field ${e.label||o}`,context:{fieldName:o,fieldType:e.type},severity:"warning"})}},s="control"in n&&n.control,d=e.type==="submit"||e.type==="reset";if(s&&!d){const{control:l,errors:i}=n,a=e.options?.fieldSpecific?.placeholder,y={control:l,errors:i,fieldConfig:{...e,label:e.label||o},t:r,placeholder:a,onChange:p(()=>{})},u=v.getControlledComponent(e.type);return u?t(u,{...y}):(C(new Error(`Unregistered field type: ${e.type}`),{userMessage:r("errors.unsupportedFieldType",{type:e.type}),context:{fieldName:o,fieldType:e.type},severity:"warning"}),t(T,{...y,fieldConfig:{...e,type:"text"}}))}const b=s&&d?{name:o,config:e,t:r,value:void 0,onChange:()=>{},error:void 0}:n,{value:f,onChange:x,error:c}=b,g=p(x),m=v.getUncontrolledComponent(e.type);return m?t(m,{name:o,label:e.label||o,value:f,onChange:g,error:c,t:r,config:e,...e.options}):t(w,{label:e.label||o,value:f,onChange:g,error:c||void 0,...e.options})}var E=h;export{h as FormFieldRenderer,E as default};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{handleError as h}from"@donotdev/core";import{getFieldRegistry as T}from"../FieldRegistry";import{ControlledTextField as S}from"./controlled";import{TextFieldComponent as g}from"./form/fields";const x=T();function w({name:r,config:e,t,...o}){const s=n=>d=>{try{n(d)}catch(C){h(C,{userMessage:`Error updating field ${e.label||r}`,context:{fieldName:r,fieldType:e.type},severity:"warning"})}},i="control"in o&&o.control,p=e.type==="submit"||e.type==="reset";if(i&&!p){const{control:n,errors:d}=o,F=e.options?.fieldSpecific?.placeholder,f={control:n,errors:d,fieldConfig:{...e,label:e.label||r},t,placeholder:F,onChange:s(()=>{})},m=x.getControlledComponent(e.type);return m?l(m,{...f}):(h(new Error(`Unregistered field type: ${e.type}`),{userMessage:t("errors.unsupportedFieldType",{type:e.type}),context:{fieldName:r,fieldType:e.type},severity:"warning"}),l(S,{...f,fieldConfig:{...e,type:"text"}}))}const b=i&&p?{name:r,config:e,t,value:void 0,onChange:()=>{},error:void 0}:o,{value:a,onChange:v,error:u}=b,y=s(v),c=x.getUncontrolledComponent(e.type);return c?l(c,{name:r,label:e.label||r,value:a,onChange:y,error:u,t,config:e,...e.options}):l(g,{label:e.label||r,value:a,onChange:y,error:u||void 0,...e.options})}var P=w;export{w as FormFieldRenderer,P as default};
@@ -1 +1 @@
1
- "use client";import{jsx as d,jsxs as i,Fragment as N}from"react/jsx-runtime";import{useState as w}from"react";import{FormProvider as C}from"react-hook-form";import{Button as s,BUTTON_VARIANT as j,Spinner as k,cn as z,Stack as a,Grid as A}from"@donotdev/components";import{useTranslation as B}from"@donotdev/core";const F=({title:c,onSubmit:m,children:g,formMethods:f,loading:n=!1,submitText:u,cancelText:v,showCancel:p=!1,onCancel:h,variant:o="default",columns:b=1,description:t})=>{const{t:e}=B("crud"),[r,l]=w(!1),y=u||e("form.submit","Submit"),x=v||e("form.cancel","Cancel"),S=async T=>{l(!0);try{await m(T)}finally{l(!1)}},L={1:"dndev-grid-cols-1",2:"dndev-grid-cols-1 dndev-md:grid-cols-2",3:"dndev-grid-cols-1 dndev-md:grid-cols-2 dndev-md:grid-cols-3",4:"dndev-grid-cols-1 dndev-md:grid-cols-2 dndev-md:grid-cols-4"};return d(C,{...f,children:d("form",{onSubmit:S,className:z("dndev-mx-auto",{default:"dndev-surface",card:"dndev-surface",minimal:""}[o]),style:o!=="minimal"?{padding:"var(--gap-lg)"}:void 0,role:"form","aria-labelledby":"form-title",noValidate:!0,children:i(a,{gap:"large",children:[i(a,{gap:"tight",children:[d("h2",{id:"form-title",style:{fontSize:"var(--font-size-2xl)",fontWeight:600,color:"var(--foreground)"},children:c}),t&&d("p",{style:{color:"var(--muted-foreground)"},children:t})]}),d(A,{cols:b,className:"dndev-w-full dndev-min-w-0",children:g}),i(a,{direction:"row",align:"center",justify:"end",style:{paddingTop:"var(--gap-md)",borderTop:"1px solid var(--border)"},children:[p&&d(s,{type:"button",variant:j.OUTLINE,onClick:h,disabled:n||r,children:x}),d(s,{type:"submit",disabled:n||r,style:{minWidth:"120px"},children:n||r?i(N,{children:[d(k,{className:"me-component-gap"}),r?e("form.submitting","Submitting..."):e("form.loading","Loading...")]}):y})]})]})})})};var I=F;export{I as default};
1
+ "use client";import{jsx as e,jsxs as r,Fragment as N}from"react/jsx-runtime";import{useState as j}from"react";import{FormProvider as w}from"react-hook-form";import{Button as s,BUTTON_VARIANT as C,Spinner as F,cn as _,Stack as i,Grid as I}from"@donotdev/components";import{useTranslation as L}from"@donotdev/core";const k=({title:m,onSubmit:c,children:u,formMethods:f,loading:n=!1,submitText:g,cancelText:v,showCancel:p=!1,onCancel:b,variant:l="default",columns:h=1,description:o})=>{const{t:d}=L("crud"),[t,a]=j(!1),y=g||d("form.submit","Submit"),S=v||d("form.cancel","Cancel"),x=async T=>{a(!0);try{await c(T)}finally{a(!1)}},z={1:"dndev-grid-cols-1",2:"dndev-grid-cols-1 dndev-md:grid-cols-2",3:"dndev-grid-cols-1 dndev-md:grid-cols-2 dndev-md:grid-cols-3",4:"dndev-grid-cols-1 dndev-md:grid-cols-2 dndev-md:grid-cols-4"};return e(w,{...f,children:e("form",{onSubmit:x,className:_("dndev-mx-auto",{default:"dndev-surface",card:"dndev-surface",minimal:""}[l]),style:l!=="minimal"?{padding:"var(--gap-lg)"}:void 0,role:"form","aria-labelledby":"form-title",noValidate:!0,children:r(i,{gap:"large",children:[r(i,{gap:"tight",children:[e("h2",{id:"form-title",style:{fontSize:"var(--font-size-2xl)",fontWeight:600,color:"var(--foreground)"},children:m}),o&&e("p",{style:{color:"var(--muted-foreground)"},children:o})]}),e(I,{cols:h,className:"dndev-w-full dndev-min-w-0",children:u}),r(i,{direction:"row",align:"center",justify:"end",style:{paddingTop:"var(--gap-md)",borderTop:"1px solid var(--border)"},children:[p&&e(s,{type:"button",variant:C.OUTLINE,onClick:b,disabled:n||t,children:S}),e(s,{type:"submit",disabled:n||t,style:{minWidth:"120px"},children:n||t?r(N,{children:[e(F,{className:"me-component-gap"}),t?d("form.submitting","Submitting..."):d("form.loading","Loading...")]}):y})]})]})})})};var E=k;export{E as default};
@@ -1 +1 @@
1
- "use client";import{jsx as n}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{AddressFieldComponent as f}from"../../form/fields";import{convertValidationRules as u}from"../types";function C(a){const{control:s,errors:r,fieldConfig:t,t:d}=a,{name:e,label:c,validation:o}=t,l=(t.options||{}).fieldSpecific;return n(p,{name:e,control:s,rules:o?u(o):void 0,render:({field:i})=>n(f,{label:d(c),value:i.value??void 0,onChange:m=>i.onChange(m),error:!!r[e],helperText:r[e]?.message,required:o?.required,enableGoogleMaps:l?.enableGoogleMaps,extractDistrictCode:l?.extractDistrictCode})})}export{C as ControlledAddressField};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{AddressFieldComponent as m}from"../../form/fields";import{convertValidationRules as u}from"../types";function h(s){const{control:a,errors:r,fieldConfig:n,t:d}=s,{name:e,label:c,validation:o}=n,t=(n.options||{}).fieldSpecific;return l(f,{name:e,control:a,rules:o?u(o):void 0,render:({field:i})=>l(m,{label:d(c),value:i.value??void 0,onChange:p=>i.onChange(p),error:!!r[e],helperText:r[e]?.message,required:o?.required,enableGoogleMaps:t?.enableGoogleMaps,extractDistrictCode:t?.extractDistrictCode})})}export{h as ControlledAddressField};
@@ -1 +1 @@
1
- "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{DateFieldComponent as f}from"../../form/fields";import{convertValidationRules as C}from"../types";function h(a){const{control:n,errors:t,fieldConfig:i,t:m}=a,{name:e,label:d,validation:o,type:s}=i,u={date:"date","datetime-local":"datetime-local",month:"month",time:"time",week:"week"}[s]||"date";return l(p,{name:e,control:n,rules:o?C(o):void 0,render:({field:r})=>l(f,{...r,label:m(d),value:r.value??null,onChange:c=>r.onChange(c),error:!!t[e],helperText:t[e]?.message,required:o?.required,mode:u})})}export{h as ControlledDateField};
1
+ "use client";import{jsx as n}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{DateFieldComponent as f}from"../../form/fields";import{convertValidationRules as C}from"../types";function j(a){const{control:l,errors:r,fieldConfig:m,t:i}=a,{name:e,label:d,validation:o,type:s}=m,c={date:"date","datetime-local":"datetime-local",month:"month",time:"time",week:"week"}[s]||"date";return n(p,{name:e,control:l,rules:o?C(o):void 0,render:({field:t})=>n(f,{...t,label:i(d),value:t.value??null,onChange:u=>t.onChange(u),error:!!r[e],helperText:r[e]?.message,required:o?.required,mode:c})})}export{j as ControlledDateField};
@@ -1 +1 @@
1
- "use client";import{jsxs as r,jsx as i}from"react/jsx-runtime";import{Plus as $,Trash2 as q}from"lucide-react";import{useFieldArray as B,Controller as D}from"react-hook-form";import{Button as y}from"@donotdev/components";import{getFieldRegistry as I}from"../../../FieldRegistry";import{convertValidationRules as R}from"../types";function j(s){switch(s){case"number":return 0;case"boolean":return!1;default:return""}}function A(s){const{control:d,errors:h,fieldConfig:c,t:n}=s,{name:m,label:f,validation:x}=c,v=c.options?.fieldSpecific??{},o=v.fields??[],l=v.direction??"row",{fields:b,append:C,remove:w}=B({control:d,name:m}),S=I(),z=()=>{if(o.length===0)return;const a={};for(const t of o)a[t.name]=j(t.type);C(a)};return o.length===0?r("div",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:[n(f),": no sub-fields configured"]}):r("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-sm)"},children:[r("div",{style:{display:"flex",alignItems:"center",gap:"var(--gap-sm)"},children:[r("span",{style:{fontSize:"var(--font-size-sm)",fontWeight:"var(--font-weight-medium)"},children:[n(f),x?.required&&i("span",{style:{color:"var(--destructive)",marginInlineStart:"var(--gap-tight)"},children:"*"})]}),i(y,{type:"button",variant:"ghost",display:"compact",icon:$,onClick:z,"aria-label":n(f)+" \u2014 add"})]}),b.map((a,t)=>r("div",{style:{display:"flex",flexDirection:l,gap:"var(--gap-sm)",alignItems:l==="row"?"flex-start":void 0},children:[o.map(e=>{const u=`${m}.${t}.${e.name}`,F={name:u,type:e.type,label:e.label,visibility:c.visibility,validation:{...e.validation??{},...e.required?{required:!0}:{}},options:e.options??{}},g=S.getControlledComponent(e.type);return g?i("div",{style:{flex:l==="row"?1:void 0},children:i(g,{control:d,errors:h,fieldConfig:F,t:n})},e.name):i("div",{style:{flex:l==="row"?1:void 0},children:i(D,{name:u,control:d,rules:e.validation?R(e.validation):void 0,render:({field:p})=>r("label",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-tight)"},children:[i("span",{style:{fontSize:"var(--font-size-xs)"},children:n(e.label)}),i("input",{className:"dndev-input",value:String(p.value??""),onChange:p.onChange,onBlur:p.onBlur})]})})},e.name)}),i(y,{type:"button",variant:"ghost",display:"compact",icon:q,onClick:()=>w(t),"aria-label":`Remove row ${t+1}`,style:{alignSelf:l==="row"?"center":"flex-end"}})]},a.id))]})}export{A as ControlledFieldArrayField};
1
+ "use client";import{jsxs as t,jsx as n}from"react/jsx-runtime";import{Plus as j,Trash2 as R}from"lucide-react";import{useFieldArray as $,Controller as q}from"react-hook-form";import{Button as y}from"@donotdev/components";import{getFieldRegistry as A}from"../../../FieldRegistry";import{convertValidationRules as B}from"../types";function D(s){switch(s){case"number":return 0;case"boolean":return!1;default:return""}}function N(s){const{control:d,errors:h,fieldConfig:c,t:o}=s,{name:m,label:p,validation:b}=c,f=c.options?.fieldSpecific??{},r=f.fields??[],l=f.direction??"row",{fields:x,append:C,remove:S}=$({control:d,name:m}),w=A(),z=()=>{if(r.length===0)return;const a={};for(const i of r)a[i.name]=D(i.type);C(a)};return r.length===0?t("div",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:[o(p),": no sub-fields configured"]}):t("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-sm)"},children:[t("div",{style:{display:"flex",alignItems:"center",gap:"var(--gap-sm)"},children:[t("span",{style:{fontSize:"var(--font-size-sm)",fontWeight:"var(--font-weight-medium)"},children:[o(p),b?.required&&n("span",{style:{color:"var(--destructive)",marginInlineStart:"var(--gap-tight)"},children:"*"})]}),n(y,{type:"button",variant:"ghost",display:"compact",icon:j,onClick:z,"aria-label":o(p)+" \u2014 add"})]}),x.map((a,i)=>t("div",{style:{display:"flex",flexDirection:l,gap:"var(--gap-sm)",alignItems:l==="row"?"flex-start":void 0},children:[r.map(e=>{const g=`${m}.${i}.${e.name}`,F={name:g,type:e.type,label:e.label,visibility:c.visibility,validation:{...e.validation??{},...e.required?{required:!0}:{}},options:e.options??{}},v=w.getControlledComponent(e.type);return v?n("div",{style:{flex:l==="row"?1:void 0},children:n(v,{control:d,errors:h,fieldConfig:F,t:o})},e.name):n("div",{style:{flex:l==="row"?1:void 0},children:n(q,{name:g,control:d,rules:e.validation?B(e.validation):void 0,render:({field:u})=>t("label",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-tight)"},children:[n("span",{style:{fontSize:"var(--font-size-xs)"},children:o(e.label)}),n("input",{className:"dndev-input",value:String(u.value??""),onChange:u.onChange,onBlur:u.onBlur})]})})},e.name)}),n(y,{type:"button",variant:"ghost",display:"compact",icon:R,onClick:()=>S(i),"aria-label":`Remove row ${i+1}`,style:{alignSelf:l==="row"?"center":"flex-end"}})]},a.id))]})}export{N as ControlledFieldArrayField};
@@ -1 +1 @@
1
- "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as c}from"react-hook-form";import{GeoPointFieldComponent as f}from"../../form/fields";import{convertValidationRules as p}from"../types";function C(a){const{control:i,errors:t,fieldConfig:s,t:m}=a,{name:o,label:d,validation:n}=s;return l(c,{name:o,control:i,rules:n?p(n):void 0,render:({field:e})=>{const g=r=>{if("target"in r)try{const u=JSON.parse(r.target.value);e.onChange(u)}catch{e.onChange({lat:0,lng:0})}else e.onChange(r||{lat:0,lng:0})};return l(f,{label:m(d),value:e.value||{lat:0,lng:0},onChange:g,error:!!t[o],helperText:t[o]?.message,required:n?.required})}})}export{C as ControlledGeoPointField};
1
+ "use client";import{jsx as a}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{GeoPointFieldComponent as p}from"../../form/fields";import{convertValidationRules as C}from"../types";function b(l){const{control:i,errors:t,fieldConfig:s,t:g}=l,{name:n,label:m,validation:o}=s;return a(u,{name:n,control:i,rules:o?C(o):void 0,render:({field:e})=>{const c=r=>{if("target"in r)try{const d=JSON.parse(r.target.value);e.onChange(d)}catch{e.onChange({lat:0,lng:0})}else e.onChange(r||{lat:0,lng:0})};return a(p,{label:g(m),value:e.value||{lat:0,lng:0},onChange:c,error:!!t[n],helperText:t[n]?.message,required:o?.required})}})}export{b as ControlledGeoPointField};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{MapFieldComponent as f}from"../../form/fields";import{convertValidationRules as g}from"../types";function C(l){const{control:i,errors:a,fieldConfig:s,t:m}=l,{name:r,label:d,validation:o}=s;return t(p,{name:r,control:i,rules:o?g(o):void 0,render:({field:e})=>{const u=n=>{if("target"in n)try{const c=JSON.parse(n.target.value);e.onChange(c)}catch{e.onChange({})}else e.onChange(n||{})};return t(f,{label:m(d),value:e.value||{},onChange:u,error:!!a[r],helperText:a[r]?.message,required:o?.required})}})}export{C as ControlledMapField};
1
+ "use client";import{jsx as a}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{MapFieldComponent as g}from"../../form/fields";import{convertValidationRules as C}from"../types";function b(l){const{control:i,errors:t,fieldConfig:s,t:m}=l,{name:r,label:c,validation:n}=s;return a(u,{name:r,control:i,rules:n?C(n):void 0,render:({field:e})=>{const p=o=>{if("target"in o)try{const d=JSON.parse(o.target.value);e.onChange(d)}catch{e.onChange({})}else e.onChange(o||{})};return a(g,{label:m(c),value:e.value||{},onChange:p,error:!!t[r],helperText:t[r]?.message,required:n?.required})}})}export{b as ControlledMapField};
@@ -1 +1 @@
1
- "use client";import{jsx as a}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{MultiInputTextFieldComponent as f}from"../../form/fields";import{convertValidationRules as C}from"../types";function v(t){const{control:l,errors:g,fieldConfig:i,t:s}=t,{name:u,label:m,validation:r,options:c={}}=i;return a(p,{name:u,control:l,rules:r?C(r):void 0,render:({field:e})=>{const d=o=>{if(Array.isArray(o))e.onChange(o);else try{const n=JSON.parse(o.target.value);e.onChange(Array.isArray(n)?n:[])}catch{e.onChange([])}};return a(f,{label:s(m),value:Array.isArray(e.value)?e.value:[],onChange:d,required:r?.required,className:c.className})}})}export{v as ControlledMultiInputField};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as d}from"react-hook-form";import{MultiInputTextFieldComponent as C}from"../../form/fields";import{convertValidationRules as g}from"../types";function x(a){const{control:l,errors:h,fieldConfig:s,t:i}=a,{name:u,label:c,validation:e,options:m={}}=s;return t(d,{name:u,control:l,rules:e?g(e):void 0,render:({field:r})=>{const p=n=>{if(Array.isArray(n))r.onChange(n);else try{const o=JSON.parse(n.target.value);r.onChange(Array.isArray(o)?o:[])}catch{r.onChange([])}};return t(C,{label:i(c),value:Array.isArray(r.value)?r.value:[],onChange:p,required:e?.required,className:m.className})}})}export{x as ControlledMultiInputField};
@@ -1 +1 @@
1
- "use client";import{jsx as n}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{RichTextComponent as f}from"../../form/fields";import{convertValidationRules as h}from"../types";function C(t){const{control:i,errors:r,fieldConfig:s,t:m,placeholder:c}=t,{name:e,label:d,validation:o,options:l={}}=s;return n(u,{name:e,control:i,rules:o?h(o):void 0,render:({field:a})=>n(f,{label:m(d),value:a.value??"",onChange:p=>a.onChange(p),error:r[e]?.message,helperText:r[e]?.message,required:o?.required,placeholder:c||l.placeholder,className:l.className})})}export{C as ControlledRichTextField};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{RichTextComponent as h}from"../../form/fields";import{convertValidationRules as f}from"../types";function R(a){const{control:i,errors:r,fieldConfig:s,t:m,placeholder:c}=a,{name:e,label:d,validation:o,options:l={}}=s;return t(u,{name:e,control:i,rules:o?f(o):void 0,render:({field:n})=>t(h,{label:m(d),value:n.value??"",onChange:p=>n.onChange(p),error:r[e]?.message,helperText:r[e]?.message,required:o?.required,placeholder:c||l.placeholder,className:l.className})})}export{R as ControlledRichTextField};
@@ -1 +1 @@
1
- "use client";import{jsx as n}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{TimestampFieldComponent as p}from"../../form/fields";import{convertValidationRules as f}from"../types";function c(t){const{control:i,errors:l,fieldConfig:a,t:m}=t,{name:e,label:s,validation:r}=a;return n(u,{name:e,control:i,rules:r?f(r):void 0,render:({field:o})=>n(p,{...o,label:m(s),value:o.value??null,onChange:d=>o.onChange(d),error:!!l[e],helperText:l[e]?.message,required:r?.required})})}export{c as ControlledTimestampField};
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as d}from"react-hook-form";import{TimestampFieldComponent as p}from"../../form/fields";import{convertValidationRules as c}from"../types";function x(l){const{control:i,errors:n,fieldConfig:a,t:m}=l,{name:e,label:s,validation:r}=a;return t(d,{name:e,control:i,rules:r?c(r):void 0,render:({field:o})=>t(p,{...o,label:m(s),value:o.value??null,onChange:u=>o.onChange(u),error:!!n[e],helperText:n[e]?.message,required:r?.required})})}export{x as ControlledTimestampField};
@@ -1 +1 @@
1
- import{ControlledAddressField as o}from"./ControlledAddressField";import{ControlledFieldArrayField as l}from"./ControlledFieldArrayField";import{ControlledDateField as e}from"./ControlledDateField";import{ControlledGeoPointField as r}from"./ControlledGeoPointField";import{ControlledMapField as d}from"./ControlledMapField";import{ControlledMultiInputField as t}from"./ControlledMultiInputField";import{ControlledRichTextField as i}from"./ControlledRichTextField";import{ControlledTimestampField as a}from"./ControlledTimestampField";export{o as ControlledAddressField,e as ControlledDateField,l as ControlledFieldArrayField,r as ControlledGeoPointField,d as ControlledMapField,t as ControlledMultiInputField,i as ControlledRichTextField,a as ControlledTimestampField};
1
+ import{ControlledAddressField as r}from"./ControlledAddressField";import{ControlledFieldArrayField as t}from"./ControlledFieldArrayField";import{ControlledDateField as i}from"./ControlledDateField";import{ControlledGeoPointField as m}from"./ControlledGeoPointField";import{ControlledMapField as x}from"./ControlledMapField";import{ControlledMultiInputField as f}from"./ControlledMultiInputField";import{ControlledRichTextField as a}from"./ControlledRichTextField";import{ControlledTimestampField as u}from"./ControlledTimestampField";export{r as ControlledAddressField,i as ControlledDateField,t as ControlledFieldArrayField,m as ControlledGeoPointField,x as ControlledMapField,f as ControlledMultiInputField,a as ControlledRichTextField,u as ControlledTimestampField};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{DocumentFieldComponent as c}from"../../form/fields";import{convertValidationRules as f}from"../types";function g(i){const{control:m,errors:r,fieldConfig:l,t:s}=i,{name:e,label:u,validation:o}=l,n=l.options||{};return t(p,{name:e,control:m,rules:o?f(o):void 0,render:({field:a})=>t(c,{name:e,label:s(u),value:a.value??null,onChange:d=>a.onChange(d),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:n.maxSize,storagePath:n.storagePath})})}export{g as ControlledDocumentField};
1
+ "use client";import{jsx as a}from"react/jsx-runtime";import{Controller as d}from"react-hook-form";import{DocumentFieldComponent as p}from"../../form/fields";import{convertValidationRules as f}from"../types";function v(i){const{control:m,errors:r,fieldConfig:n,t:s}=i,{name:e,label:u,validation:o}=n,t=n.options||{};return a(d,{name:e,control:m,rules:o?f(o):void 0,render:({field:l})=>a(p,{name:e,label:s(u),value:l.value??null,onChange:c=>l.onChange(c),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:t.maxSize,storagePath:t.storagePath})})}export{v as ControlledDocumentField};
@@ -1 +1 @@
1
- "use client";import{jsx as i}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{FileFieldComponent as f}from"../../form/fields";import{convertValidationRules as c}from"../types";function g(n){const{control:m,errors:r,fieldConfig:l,t:s}=n,{name:e,label:u,validation:o}=l,a=l.options||{};return i(p,{name:e,control:m,rules:o?c(o):void 0,render:({field:t})=>i(f,{name:e,label:s(u),value:t.value??null,onChange:d=>t.onChange(d),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:a.maxSize,storagePath:a.storagePath})})}export{g as ControlledFileField};
1
+ "use client";import{jsx as i}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{FileFieldComponent as c}from"../../form/fields";import{convertValidationRules as f}from"../types";function F(a){const{control:s,errors:r,fieldConfig:n,t:m}=a,{name:e,label:u,validation:o}=n,l=n.options||{};return i(p,{name:e,control:s,rules:o?f(o):void 0,render:({field:t})=>i(c,{name:e,label:m(u),value:t.value??null,onChange:d=>t.onChange(d),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:l.maxSize,storagePath:l.storagePath})})}export{F as ControlledFileField};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{ImageFieldComponent as f}from"../../form/fields";import{convertValidationRules as g}from"../types";function c(i){const{control:m,errors:r,fieldConfig:a,t:s}=i,{name:e,label:u,validation:o}=a,l=a.options||{};return t(p,{name:e,control:m,rules:o?g(o):void 0,render:({field:n})=>t(f,{name:e,label:s(u),value:n.value??null,onChange:d=>n.onChange(d),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:l.maxSize,storagePath:l.storagePath})})}export{c as ControlledImageField};
1
+ "use client";import{jsx as a}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{ImageFieldComponent as c}from"../../form/fields";import{convertValidationRules as f}from"../types";function v(i){const{control:m,errors:r,fieldConfig:n,t:s}=i,{name:e,label:u,validation:o}=n,t=n.options||{};return a(p,{name:e,control:m,rules:o?f(o):void 0,render:({field:l})=>a(c,{name:e,label:s(u),value:l.value??null,onChange:d=>l.onChange(d),error:!!r[e],helperText:r[e]?.message,required:o?.required,multiple:!1,maxFiles:1,maxSize:t.maxSize,storagePath:t.storagePath})})}export{v as ControlledImageField};
@@ -1 +1 @@
1
- "use client";import{jsx as n}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{DocumentFieldComponent as p}from"../../form/fields";import{convertValidationRules as v}from"../types";function x(i){const{control:m,errors:l,fieldConfig:t,t:s}=i,{name:r,label:u,validation:o}=t,a=t.options||{};return n(f,{name:r,control:m,rules:o?v(o):void 0,render:({field:e})=>{const d=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return n(p,{name:r,label:s(u),value:d,onChange:c=>e.onChange(c),error:!!l[r],helperText:l[r]?.message,required:o?.required,multiple:!0,maxFiles:a.maxFiles??10,maxSize:a.maxSize,storagePath:a.storagePath})}})}export{x as ControlledMultiDocumentField};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as x}from"react-hook-form";import{DocumentFieldComponent as d}from"../../form/fields";import{convertValidationRules as v}from"../types";function F(i){const{control:u,errors:t,fieldConfig:a,t:m}=i,{name:r,label:s,validation:o}=a,n=a.options||{};return l(x,{name:r,control:u,rules:o?v(o):void 0,render:({field:e})=>{const c=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return l(d,{name:r,label:m(s),value:c,onChange:p=>e.onChange(p),error:!!t[r],helperText:t[r]?.message,required:o?.required,multiple:!0,maxFiles:n.maxFiles??10,maxSize:n.maxSize,storagePath:n.storagePath})}})}export{F as ControlledMultiDocumentField};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as v}from"react-hook-form";import{FileFieldComponent as c}from"../../form/fields";import{convertValidationRules as f}from"../types";function x(n){const{control:s,errors:a,fieldConfig:i,t:m}=n,{name:r,label:u,validation:o}=i,l=i.options||{};return t(v,{name:r,control:s,rules:o?f(o):void 0,render:({field:e})=>{const d=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return t(c,{name:r,label:m(u),value:d,onChange:p=>e.onChange(p),error:!!a[r],helperText:a[r]?.message,required:o?.required,multiple:!0,maxFiles:l.maxFiles??10,maxSize:l.maxSize,storagePath:l.storagePath})}})}export{x as ControlledMultiFileField};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as x}from"react-hook-form";import{FileFieldComponent as d}from"../../form/fields";import{convertValidationRules as v}from"../types";function f(i){const{control:s,errors:t,fieldConfig:a,t:u}=i,{name:r,label:m,validation:o}=a,n=a.options||{};return l(x,{name:r,control:s,rules:o?v(o):void 0,render:({field:e})=>{const p=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return l(d,{name:r,label:u(m),value:p,onChange:c=>e.onChange(c),error:!!t[r],helperText:t[r]?.message,required:o?.required,multiple:!0,maxFiles:n.maxFiles??10,maxSize:n.maxSize,storagePath:n.storagePath})}})}export{f as ControlledMultiFileField};
@@ -1 +1 @@
1
- "use client";import{jsx as t}from"react/jsx-runtime";import{Controller as c}from"react-hook-form";import{ImageFieldComponent as f}from"../../form/fields";import{convertValidationRules as g}from"../types";function v(n){const{control:m,errors:l,fieldConfig:i,t:s}=n,{name:r,label:u,validation:o}=i,a=i.options||{};return t(c,{name:r,control:m,rules:o?g(o):void 0,render:({field:e})=>{const d=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return t(f,{name:r,label:s(u),value:d,onChange:p=>e.onChange(p),error:!!l[r],helperText:l[r]?.message,required:o?.required,multiple:!0,maxFiles:a.maxFiles??10,maxSize:a.maxSize,storagePath:a.fieldSpecific?.storagePath})}})}export{v as ControlledMultiImageField};
1
+ "use client";import{jsx as l}from"react/jsx-runtime";import{Controller as d}from"react-hook-form";import{ImageFieldComponent as g}from"../../form/fields";import{convertValidationRules as x}from"../types";function F(i){const{control:m,errors:n,fieldConfig:t,t:s}=i,{name:r,label:u,validation:o}=t,a=t.options||{};return l(d,{name:r,control:m,rules:o?x(o):void 0,render:({field:e})=>{const c=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return l(g,{name:r,label:s(u),value:c,onChange:p=>e.onChange(p),error:!!n[r],helperText:n[r]?.message,required:o?.required,multiple:!0,maxFiles:a.maxFiles??10,maxSize:a.maxSize,storagePath:a.fieldSpecific?.storagePath})}})}export{F as ControlledMultiImageField};
@@ -1 +1 @@
1
- import{ControlledDocumentField as l}from"./ControlledDocumentField";import{ControlledFileField as o}from"./ControlledFileField";import{ControlledImageField as e}from"./ControlledImageField";import{ControlledMultiDocumentField as t}from"./ControlledMultiDocumentField";import{ControlledMultiFileField as i}from"./ControlledMultiFileField";import{ControlledMultiImageField as r}from"./ControlledMultiImageField";export{l as ControlledDocumentField,o as ControlledFileField,e as ControlledImageField,t as ControlledMultiDocumentField,i as ControlledMultiFileField,r as ControlledMultiImageField};
1
+ import{ControlledDocumentField as l}from"./ControlledDocumentField";import{ControlledFileField as t}from"./ControlledFileField";import{ControlledImageField as i}from"./ControlledImageField";import{ControlledMultiDocumentField as n}from"./ControlledMultiDocumentField";import{ControlledMultiFileField as f}from"./ControlledMultiFileField";import{ControlledMultiImageField as x}from"./ControlledMultiImageField";export{l as ControlledDocumentField,t as ControlledFileField,i as ControlledImageField,n as ControlledMultiDocumentField,f as ControlledMultiFileField,x as ControlledMultiImageField};
@@ -1 +1 @@
1
- import{convertValidationRules as o,convertPatternToRegex as e}from"./types";export*from"./input";export*from"./select";export*from"./file";export*from"./complex";export{e as convertPatternToRegex,o as convertValidationRules};
1
+ import{convertValidationRules as e,convertPatternToRegex as t}from"./types";export*from"./input";export*from"./select";export*from"./file";export*from"./complex";export{t as convertPatternToRegex,e as convertValidationRules};