@donotdev/crud 0.0.18 → 0.0.19
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.
- package/dist/CrudService.js +2 -2
- package/dist/CrudStore.js +1 -1
- package/dist/FieldRegistry.js +1 -1
- package/dist/adapters/FunctionsAdapter.js +1 -1
- package/dist/components/CrudButton.d.ts.map +1 -1
- package/dist/components/CrudButton.js +1 -1
- package/dist/components/CrudCard.js +1 -1
- package/dist/components/DateFilter.js +1 -1
- package/dist/components/DisplayFieldRenderer.d.ts +2 -4
- package/dist/components/DisplayFieldRenderer.d.ts.map +1 -1
- package/dist/components/DisplayFieldRenderer.js +1 -1
- package/dist/components/DisplayThumbnail.js +1 -1
- package/dist/components/EntityFilters.d.ts.map +1 -1
- package/dist/components/EntityFilters.js +1 -1
- package/dist/components/FormFieldRenderer.js +1 -1
- package/dist/components/FormLayout.js +1 -1
- package/dist/components/controlled/complex/ControlledAddressField.js +1 -1
- package/dist/components/controlled/complex/ControlledDateField.js +1 -1
- package/dist/components/controlled/complex/ControlledFieldArrayField.js +1 -1
- package/dist/components/controlled/complex/ControlledGeoPointField.js +1 -1
- package/dist/components/controlled/complex/ControlledMapField.js +1 -1
- package/dist/components/controlled/complex/ControlledMultiInputField.js +1 -1
- package/dist/components/controlled/complex/ControlledRichTextField.js +1 -1
- package/dist/components/controlled/complex/ControlledTimestampField.js +1 -1
- package/dist/components/controlled/complex/index.js +1 -1
- package/dist/components/controlled/file/ControlledDocumentField.js +1 -1
- package/dist/components/controlled/file/ControlledFileField.js +1 -1
- package/dist/components/controlled/file/ControlledImageField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiDocumentField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiFileField.js +1 -1
- package/dist/components/controlled/file/ControlledMultiImageField.js +1 -1
- package/dist/components/controlled/file/index.js +1 -1
- package/dist/components/controlled/index.js +1 -1
- package/dist/components/controlled/input/ControlledCheckboxField.js +1 -1
- package/dist/components/controlled/input/ControlledCurrencyField.js +1 -1
- package/dist/components/controlled/input/ControlledDurationField.js +1 -1
- package/dist/components/controlled/input/ControlledGdprConsentField.js +1 -1
- package/dist/components/controlled/input/ControlledNumberField.js +1 -1
- package/dist/components/controlled/input/ControlledPasswordField.js +1 -1
- package/dist/components/controlled/input/ControlledPhoneField.js +1 -1
- package/dist/components/controlled/input/ControlledPriceField.js +1 -1
- package/dist/components/controlled/input/ControlledRangeField.js +1 -1
- package/dist/components/controlled/input/ControlledRatingField.js +1 -1
- package/dist/components/controlled/input/ControlledSwitchField.js +1 -1
- package/dist/components/controlled/input/ControlledTextField.js +1 -1
- package/dist/components/controlled/input/ControlledTextareaField.js +1 -1
- package/dist/components/controlled/input/index.js +1 -1
- package/dist/components/controlled/select/ControlledComboboxField.js +1 -1
- package/dist/components/controlled/select/ControlledDropdownField.js +1 -1
- package/dist/components/controlled/select/ControlledMultiDropdownField.js +1 -1
- package/dist/components/controlled/select/ControlledRadioField.js +1 -1
- package/dist/components/controlled/select/ControlledReferenceField.d.ts +20 -0
- package/dist/components/controlled/select/ControlledReferenceField.d.ts.map +1 -0
- package/dist/components/controlled/select/ControlledReferenceField.js +1 -0
- package/dist/components/controlled/select/ControlledYearField.js +1 -1
- package/dist/components/controlled/select/index.d.ts +1 -0
- package/dist/components/controlled/select/index.d.ts.map +1 -1
- package/dist/components/controlled/select/index.js +1 -1
- package/dist/components/controlled/types.js +1 -1
- package/dist/components/fields/display/AvatarFieldDisplay.js +1 -1
- package/dist/components/fields/display/BadgeFieldDisplay.js +1 -1
- package/dist/components/fields/display/ButtonFieldDisplay.js +1 -1
- package/dist/components/fields/display/CheckboxFieldDisplay.js +1 -1
- package/dist/components/fields/display/DateFieldDisplay.js +1 -1
- package/dist/components/fields/display/DropdownDisplay.js +1 -1
- package/dist/components/fields/display/FileFieldDisplay.js +1 -1
- package/dist/components/fields/display/GeoPointFieldDisplay.js +1 -1
- package/dist/components/fields/display/HiddenFieldDisplay.js +1 -1
- package/dist/components/fields/display/ImageFieldDisplay.js +1 -1
- package/dist/components/fields/display/LinkFieldDisplay.js +1 -1
- package/dist/components/fields/display/MapFieldDisplay.js +1 -1
- package/dist/components/fields/display/MultiDropdownDisplay.js +1 -1
- package/dist/components/fields/display/MultiInputTextFieldDisplay.js +1 -1
- package/dist/components/fields/display/NumberFieldDisplay.js +1 -1
- package/dist/components/fields/display/PasswordFieldDisplay.js +1 -1
- package/dist/components/fields/display/PhoneNumberDisplay.js +1 -1
- package/dist/components/fields/display/RadioFieldDisplay.js +1 -1
- package/dist/components/fields/display/RangeFieldDisplay.js +1 -1
- package/dist/components/fields/display/ReferenceFieldDisplay.js +1 -1
- package/dist/components/fields/display/RichTextDisplay.js +2 -2
- package/dist/components/fields/display/TextAreaDisplay.js +1 -1
- package/dist/components/fields/display/TextFieldDisplay.js +1 -1
- package/dist/components/fields/display/TimestampFieldDisplay.js +1 -1
- package/dist/components/fields/display/index.js +1 -1
- package/dist/components/form/fields/AddressFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/AddressFieldComponent.js +1 -1
- package/dist/components/form/fields/AvatarFieldComponent.js +1 -1
- package/dist/components/form/fields/BadgeFieldComponent.js +1 -1
- package/dist/components/form/fields/ButtonFieldComponent.js +1 -1
- package/dist/components/form/fields/CheckboxFieldComponent.js +1 -1
- package/dist/components/form/fields/ComboboxComponent.js +1 -1
- package/dist/components/form/fields/CurrencyFieldComponent.js +1 -1
- package/dist/components/form/fields/DateFieldComponent.js +1 -1
- package/dist/components/form/fields/DocumentFieldComponent.js +1 -1
- package/dist/components/form/fields/DropdownComponent.js +1 -1
- package/dist/components/form/fields/DurationFieldComponent.js +1 -1
- package/dist/components/form/fields/FileFieldComponent.js +1 -1
- package/dist/components/form/fields/GdprConsentFieldComponent.js +1 -1
- package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
- package/dist/components/form/fields/HiddenFieldComponent.js +1 -1
- package/dist/components/form/fields/ImageFieldComponent.js +1 -1
- package/dist/components/form/fields/MapFieldComponent.js +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.d.ts.map +1 -1
- package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
- package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
- package/dist/components/form/fields/NumberFieldComponent.js +1 -1
- package/dist/components/form/fields/PasswordFieldComponent.js +1 -1
- package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
- package/dist/components/form/fields/PriceFieldComponent.js +1 -1
- package/dist/components/form/fields/RadioFieldComponent.js +1 -1
- package/dist/components/form/fields/RangeFieldComponent.js +1 -1
- package/dist/components/form/fields/RatingFieldComponent.js +1 -1
- package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
- package/dist/components/form/fields/RichTextComponent.js +1 -1
- package/dist/components/form/fields/SwitchFieldComponent.d.ts.map +1 -1
- package/dist/components/form/fields/SwitchFieldComponent.js +1 -1
- package/dist/components/form/fields/TextAreaComponent.js +1 -1
- package/dist/components/form/fields/TextFieldComponent.js +1 -1
- package/dist/components/form/fields/TimestampFieldComponent.js +1 -1
- package/dist/components/form/fields/index.js +1 -1
- package/dist/components/form/fields/internal/TiptapEditor.js +2 -2
- package/dist/components/form/internal/ImageViewerDialog.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/contexts/UploadContext.js +1 -1
- package/dist/contexts/index.js +1 -1
- package/dist/fieldTypeRegistry.d.ts +3 -1
- package/dist/fieldTypeRegistry.d.ts.map +1 -1
- package/dist/fieldTypeRegistry.js +1 -1
- package/dist/forms/hooks/index.js +1 -1
- package/dist/forms/hooks/useController.js +1 -1
- package/dist/forms/hooks/useEntityField.js +1 -1
- package/dist/forms/hooks/useEntityForm.js +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/forms/utils/buildInitialValues.js +1 -1
- package/dist/forms/utils/getFieldsForOperation.js +1 -1
- package/dist/forms/utils/index.js +1 -1
- package/dist/forms/utils/isFieldEditable.js +1 -1
- package/dist/forms/utils/translateFieldLabel.js +1 -1
- package/dist/forms/utils/validateEntity.js +1 -1
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useCrudFilters.js +1 -1
- package/dist/hooks/useEntityFavorites.js +1 -1
- package/dist/hooks/useFieldConditions.d.ts +27 -0
- package/dist/hooks/useFieldConditions.d.ts.map +1 -0
- package/dist/hooks/useFieldConditions.js +1 -0
- package/dist/hooks/useFileUpload.js +1 -1
- package/dist/hooks/useReferenceResolver.d.ts +15 -0
- package/dist/hooks/useReferenceResolver.d.ts.map +1 -0
- package/dist/hooks/useReferenceResolver.js +1 -0
- package/dist/hooks/useRelatedItems.js +1 -1
- package/dist/hooks/useUnsavedChangesWarning.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/registerBuiltinFieldTypes.d.ts.map +1 -1
- package/dist/registerBuiltinFieldTypes.js +1 -1
- package/dist/stores/FormStore.js +1 -1
- package/dist/stores/UploadStore.js +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.js +1 -1
- package/dist/useBaseCrudList.js +1 -1
- package/dist/useCrud.js +1 -1
- package/dist/useCrudCardList.d.ts.map +1 -1
- package/dist/useCrudCardList.js +1 -1
- package/dist/useCrudList.js +1 -1
- package/dist/utils/clientListProcessing.js +1 -1
- package/dist/utils/collections.js +1 -1
- package/dist/utils/fileStorage.js +1 -1
- package/dist/utils/imageProcessing.d.ts +1 -3
- package/dist/utils/imageProcessing.d.ts.map +1 -1
- package/dist/utils/imageProcessing.js +1 -1
- package/dist/utils/imageStorage.js +1 -1
- package/dist/utils/imageUtils.js +1 -1
- package/dist/utils/matchesFilter.d.ts.map +1 -1
- package/dist/utils/matchesFilter.js +1 -1
- package/dist/utils/mergeWithOptimistic.js +1 -1
- package/dist/utils/sanitizeHtml.js +1 -1
- package/dist/utils/scopeUtils.js +1 -1
- package/dist/utils/uploadValidation.js +1 -1
- package/dist/workflows/WorkflowPersistence.d.ts +31 -0
- package/dist/workflows/WorkflowPersistence.d.ts.map +1 -0
- package/dist/workflows/WorkflowPersistence.js +1 -0
- package/dist/workflows/defineWorkflow.d.ts +92 -0
- package/dist/workflows/defineWorkflow.d.ts.map +1 -0
- package/dist/workflows/defineWorkflow.js +1 -0
- package/dist/workflows/index.d.ts +15 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +1 -0
- package/dist/workflows/useEntityWorkflow.d.ts +54 -0
- package/dist/workflows/useEntityWorkflow.d.ts.map +1 -0
- package/dist/workflows/useEntityWorkflow.js +1 -0
- package/package.json +3 -3
package/dist/CrudService.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{toast as
|
|
1
|
+
import{toast as p}from"@donotdev/components";import{createSingleton as _,handleError as d,getQueryClient as w,getI18nInstance as y,hasProvider as E,getProvider as C,hasRestrictedVisibility as A}from"@donotdev/core";import{LIST_SCHEMA_TYPE as f}from"@donotdev/core";import{CRUD_OPERATION as h}from"./types";const m=1/0,U=1e3*60*30;class L{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&&A(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(!E("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=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 h=u.items;return i===y.DELETE?(h=u.items.filter(d=>d!=null&&typeof d=="object"&&d.id!==e),{...u,items:h,total:Math.max(0,(u.total??h.length)-1)}):i===y.ADD&&s?(h=[...u.items,{...s,id:e}],{...u,items:h,total:(u.total??u.items.length)+1}):(i===y.UPDATE||i===y.SET)&&s&&u.items.some(n=>n!=null&&typeof n=="object"&&n.id===e)?(h=u.items.map(n=>n==null||typeof n!="object"||n.id!==e?n:i===y.SET?{...s,id:e}:{...n,...s}),{...u,items:h}):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(h=>h!=null&&typeof h=="object"&&h.id===e)?r.map(h=>h==null||typeof h!="object"||h.id!==e?h:i===y.SET?{...s,id:e}:{...h,...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]}),h=[];for(const[,n]of u)n&&typeof n=="object"&&"items"in n?h.push(...n.items):Array.isArray(n)&&h.push(...n);if(h.length===0)return null;const d=e;for(const n of a){if(!n.fields.every(p=>d[p]!=null&&d[p]!==""))continue;const g=h.find(p=>n.fields.every(w=>{const C=typeof d[w]=="string"?d[w].toLowerCase():d[w],E=typeof p[w]=="string"?p[w].toLowerCase():p[w];return C===E}));if(g){if(n.findOrCreate)return g.id;const p=n.fields.join(" + ");throw f(new Error(n.errorMessage||`Duplicate ${p}`),{userMessage:n.errorMessage||`A record with this ${p} 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");return this._assertCanAccess(t,s),await this.adapter.get(t,e,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&&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");return this._assertCanAccess(t,s),await this.adapter.query(t,e,s,a)}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=c();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 h=this._getPiiFields(i),d=h.length>0&&this.security?this.security.encryptPii(s,h):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 n=c(),o=this._getEntityName(t);m("success",n.t("messages.updateSuccess",{ns:"crud",entity:o}))}}catch(h){u&&this._updateListCaches(t,e,u,y.SET),this.store&&this.store.getState().rejectUpdate(t,e);const d=f(h,{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),h=u?{...u,...s}:{...s,id:e};this.store&&this.store.getState().updateOptimistic(t,e,h,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):[],n=d.length>0&&this.security?this.security.encryptPii(s,d):s;if(await this.adapter.update(t,e,n),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=c(),g=this._getEntityName(t);m("success",o.t("messages.updateSuccess",{ns:"crud",entity:g}))}}catch(d){u?this._updateListCaches(t,e,u,y.UPDATE):this.invalidateCollection(t),this.store&&this.store.getState().rejectUpdate(t,e);const n=f(d,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,n),n}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=c(),u=this._getEntityName(t);m("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),h=u.length>0&&this.security?this.security.encryptPii(e,u):e,d=await this.adapter.add(t,h,s),n=d.id,o=d.data;if(this._updateListCaches(t,r,null,y.DELETE),this._updateListCaches(t,n,o,y.ADD),this.store&&this.store.getState().confirmOptimistic(t,r,n,o),this._auditCrud("crud.create",t,n),this._shouldShowSuccessToast(i)){const g=c(),p=this._getEntityName(t);m("success",g.t("messages.createSuccess",{ns:"crud",entity:p}))}return n}catch(u){this._updateListCaches(t,r,null,y.DELETE),this.store&&this.store.getState().rejectOptimistic(t,r);const h=f(u,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,h),h}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)],h=>h?{...h,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 h=await this.adapter.add(t,e,s),d=h.id,n=h.data;if(this._updateListCaches(t,r,null,y.DELETE),this._updateListCaches(t,d,n,y.ADD),this.store&&this.store.getState().confirmOptimistic(t,r,d,n),this._auditCrud("crud.create",t,d),this._shouldShowSuccessToast(i)){const o=c(),g=this._getEntityName(t);m("success",o.t("messages.createSuccess",{ns:"crud",entity:g}))}return n}catch(h){throw this._updateListCaches(t,r,null,y.DELETE),this.store&&this.store.getState().rejectOptimistic(t,r),f(h,{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),h=u?{...u,...s,_optimistic:!0}:{...s,id:e,_optimistic:!0};this.store&&u&&this.store.getState().updateOptimistic(t,e,h,u);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.update(t,e,s);const{_optimistic:d,...n}=h;if(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=c(),g=this._getEntityName(t);m("success",o.t("messages.updateSuccess",{ns:"crud",entity:g}))}return n}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=c(),u=this._getEntityName(t);m("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 O=A(()=>new F);export{O as getCrudService};
|
|
9
|
+
configureProviders({ crud: new SupabaseCrudAdapter(sb) }) // Supabase direct (RLS)`);this.adapter=C("crud"),this.store&&this.store.getState().setCrudService(this)}}getQueryClient(){return w()}getListQueryOptions(t,e,i,r,o=f.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 c=a.items;return r===h.DELETE?(c=a.items.filter(n=>n!=null&&typeof n=="object"&&n.id!==e),{...a,items:c,total:Math.max(0,(a.total??c.length)-1)}):r===h.ADD&&i?(c=[...a.items,{...i,id:e}],{...a,items:c,total:(a.total??a.items.length)+1}):(r===h.UPDATE||r===h.SET)&&i&&a.items.some(n=>n!=null&&typeof n=="object"&&n.id===e)?(c=a.items.map(n=>n==null||typeof n!="object"||n.id!==e?n:r===h.SET?{...i,id:e}:{...n,...i}),{...a,items:c}):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[,c]of o)c&&typeof c=="object"&&"items"in c?s.push(...c.items):Array.isArray(c)&&s.push(...c);if(s.length===0)return null;const a=e;for(const c of r){if(!c.fields.every(u=>a[u]!=null&&a[u]!==""))continue;const n=s.find(u=>c.fields.every(l=>{const g=typeof a[l]=="string"?a[l].toLowerCase():a[l],S=typeof u[l]=="string"?u[l].toLowerCase():u[l];return g===S}));if(n){if(c.findOrCreate)return n.id;const u=c.fields.join(" + ");throw d(new Error(c.errorMessage||`Duplicate ${u}`),{userMessage:c.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=d(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");return this._assertCanAccess(t,i),await this.adapter.get(t,e,i)}catch(o){const s=d(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=f.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=d(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=f.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");return this._assertCanAccess(t,i),await this.adapter.query(t,e,i,o)}catch(s){const a=d(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),c=a.length>0&&this.security?this.security.encryptPii(i,a):i;if(await this.adapter.set(t,e,c,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 n=y(),u=this._getEntityName(t);p("success",n.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 c=d(a,{userMessage:`Failed to save ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,c),c}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 c=r?this._getPiiFields(r):[],n=c.length>0&&this.security?this.security.encryptPii(i,c):i;if(await this.adapter.update(t,e,n),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(),l=this._getEntityName(t);p("success",u.t("messages.updateSuccess",{ns:"crud",entity:l}))}}catch(c){s?this._updateListCaches(t,e,s,h.UPDATE):this.invalidateCollection(t),this.store&&this.store.getState().rejectUpdate(t,e);const n=d(c,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,n),n}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=d(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),c=a.length>0&&this.security?this.security.encryptPii(e,a):e,n=await this.adapter.add(t,c,i),u=n.id,l=n.data;if(this._updateListCaches(t,s,null,h.DELETE),this._updateListCaches(t,u,l,h.ADD),this.store&&this.store.getState().confirmOptimistic(t,s,u,l),this._auditCrud("crud.create",t,u),this._shouldShowSuccessToast(r)){const g=y(),S=this._getEntityName(t);p("success",g.t("messages.createSuccess",{ns:"crud",entity:S}))}return u}catch(a){this._updateListCaches(t,s,null,h.DELETE),this.store&&this.store.getState().rejectOptimistic(t,s);const c=d(a,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,c),c}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,d(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,d(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([],d(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)],c=>c?{...c,items:s}:{items:s}),i(s,a)},r)):()=>{}:(i([],new Error("Adapter not initialized")),()=>{})}catch(o){return i([],d(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 c=await this.adapter.add(t,e,i),n=c.id,u=c.data;if(this._updateListCaches(t,s,null,h.DELETE),this._updateListCaches(t,n,u,h.ADD),this.store&&this.store.getState().confirmOptimistic(t,s,n,u),this._auditCrud("crud.create",t,n),this._shouldShowSuccessToast(r)){const l=y(),g=this._getEntityName(t);p("success",l.t("messages.createSuccess",{ns:"crud",entity:g}))}return u}catch(c){throw this._updateListCaches(t,s,null,h.DELETE),this.store&&this.store.getState().rejectOptimistic(t,s),d(c,{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:c,...n}=a;if(this._updateListCaches(t,e,n,h.UPDATE),this.store&&this.store.getState().confirmUpdate(t,e),this._auditCrud("crud.update",t,e),this._shouldShowSuccessToast(o)){const u=y(),l=this._getEntityName(t);p("success",u.t("messages.updateSuccess",{ns:"crud",entity:l}))}return n}catch(c){throw s&&this._updateListCaches(t,e,s,h.UPDATE),this.store&&this.store.getState().rejectUpdate(t,e),d(c,{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),d(o,{userMessage:`Failed to delete ${t}`,showNotification:!0})}}}const T=_(()=>new L);export{T as getCrudService};
|
package/dist/CrudStore.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDoNotDevStore as d}from"@donotdev/core";import{OPTIMISTIC_STATUSES as
|
|
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:(s,n)=>({...f,setCrudService:t=>{s({crudService:t})},setHideSuccessToasts:t=>{s({hideSuccessToasts:t})},setLoading:(t,c)=>{s(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,loading:c}}}})},setError:(t,c)=>{s(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,error:c,loading:!1}}}})},setFilters:(t,c)=>{s(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,ui:{...i.ui,filters:c}}}}})},setShowFavoritesOnly:(t,c)=>{s(o=>{const i=o.collections[t]||r();return{collections:{...o.collections,[t]:{...i,ui:{...i.ui,showFavoritesOnly:c}}}}})},getFilters:t=>n().collections[t]?.ui?.filters||{},getShowFavoritesOnly:t=>n().collections[t]?.ui?.showFavoritesOnly||!1,clearCollection:t=>{s(c=>{const{[t]:o,...i}=c.collections;return{collections:i}})},clearError:t=>{s(c=>{const o=c.collections[t];return o?{collections:{...c.collections,[t]:{...o,error:null}}}:c})},addOptimistic:(t,c,o)=>{s(i=>{const e=i.collections[t]||r();return{collections:{...i.collections,[t]:{...e,optimistic:{...e.optimistic,[c]:{tempId:c,originalData:null,optimisticData:o,status:u.PENDING,operation:a.ADD}},lastUpdated:Date.now()}}}})},confirmOptimistic:(t,c,o,i)=>{s(e=>{const l=e.collections[t];if(!l)return e;const{[c]:p,...m}=l.optimistic;return{collections:{...e.collections,[t]:{...l,optimistic:m,lastUpdated:Date.now()}}}})},rejectOptimistic:(t,c)=>{s(o=>{const i=o.collections[t];if(!i)return o;const{[c]:e,...l}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:l,lastUpdated:Date.now()}}}})},updateOptimistic:(t,c,o,i)=>{s(e=>{const l=e.collections[t]||r();return{collections:{...e.collections,[t]:{...l,optimistic:{...l.optimistic,[c]:{tempId:c,originalData:i,optimisticData:o,status:u.PENDING,operation:a.UPDATE}},lastUpdated:Date.now()}}}})},confirmUpdate:(t,c)=>{s(o=>{const i=o.collections[t];if(!i)return o;const{[c]:e,...l}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:l}}}})},rejectUpdate:(t,c)=>{s(o=>{const i=o.collections[t];if(!i)return o;const e=i.optimistic[c];if(!e||e.operation!==a.UPDATE)return o;const{[c]:l,...p}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:p,lastUpdated:Date.now()}}}})},deleteOptimistic:(t,c,o)=>{s(i=>{const e=i.collections[t];return e?{collections:{...i.collections,[t]:{...e,optimistic:{...e.optimistic,[c]:{tempId:c,originalData:o,optimisticData:null,status:u.PENDING,operation:a.DELETE}},lastUpdated:Date.now()}}}:i})},confirmDelete:(t,c)=>{s(o=>{const i=o.collections[t];if(!i)return o;const{[c]:e,...l}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:l}}}})},rejectDelete:(t,c)=>{s(o=>{const i=o.collections[t];if(!i)return o;const e=i.optimistic[c];if(!e||e.operation!==a.DELETE)return o;const{[c]:l,...p}=i.optimistic;return{collections:{...o.collections,[t]:{...i,optimistic:p,lastUpdated:Date.now()}}}})},getLoading:t=>n().collections[t]?.loading||!1,getError:t=>n().collections[t]?.error||null,isOptimistic:(t,c)=>n().collections[t]?.optimistic[c]?.status==="pending",getOptimisticStatus:(t,c)=>n().collections[t]?.optimistic[c]?.status??null,getOptimisticData:(t,c)=>n().collections[t]?.optimistic[c]?.optimisticData??null})});export{E as useCrudStore};
|
package/dist/FieldRegistry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";class
|
|
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 +1 @@
|
|
|
1
|
-
import{hasProvider as
|
|
1
|
+
import{hasProvider as w,getProvider as h,wrapCrudError as l,validateWithSchema as o}from"@donotdev/core";import{LIST_SCHEMA_TYPE as u}from"@donotdev/core";let c=null;class p{serverSideOnly=!0;async getCallable(){if(w("callable"))return h("callable");if(!c){const{FirebaseCallableProvider:t}=await import("@donotdev/firebase");c=new t}return c}async getCallableFn(t){const a=await this.getCallable();return async i=>({data:await a.call(t,i)})}async get(t,a,i){const n=`get_${t}`,s=await this.getCallableFn(n);try{const e=(await s({id:a})).data;return i?o(i,e,"FunctionsAdapter.get"):e}catch(e){throw l(e,"FunctionsAdapter","get",t,a)}}async set(t,a,i,n){const s=o(n,i,"FunctionsAdapter.set"),e=`update_${t}`,d=await this.getCallableFn(e);try{await d({id:a,payload:s})}catch(r){throw l(r,"FunctionsAdapter","set",t,a)}}async update(t,a,i){const n=`update_${t}`,s=await this.getCallableFn(n);try{await s({id:a,payload:i})}catch(e){throw l(e,"FunctionsAdapter","update",t,a)}}async delete(t,a){const i=`delete_${t}`,n=await this.getCallableFn(i);try{await n({id:a})}catch(s){throw l(s,"FunctionsAdapter","delete",t,a)}}async add(t,a,i){const n=o(i,a,"FunctionsAdapter.add"),s=`create_${t}`,e=await this.getCallableFn(s);try{const d=await e({payload:n});if(!d.data)throw l(new Error("Create function returned no data"),"FunctionsAdapter","add",t);return{id:d.data.id,data:d.data}}catch(d){throw l(d,"FunctionsAdapter","add",t)}}async query(t,a,i,n=u.LIST){const s=n===u.LIST_CARD?`listCard_${t}`:`list_${t}`,e={};a.where&&(e.where=a.where.map(r=>[r.field,r.operator,r.value])),a.orderBy&&(e.orderBy=a.orderBy.map(r=>[r.field,r.direction||"asc"])),a.limit&&(e.limit=a.limit),a.startAfter&&(e.startAfterId=a.startAfter);const d=await this.getCallableFn(s);try{const r=await d(e);if(!r.data)throw l(new Error("Query function returned no data"),"FunctionsAdapter","query",t);return{items:r.data.items,total:r.data.count,hasMore:r.data.hasMore,lastVisible:r.data.lastVisible}}catch(r){throw l(r,"FunctionsAdapter","query",t)}}subscribe(){return()=>{}}subscribeToCollection(){return()=>{}}}export{p as FunctionsAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrudButton.d.ts","sourceRoot":"","sources":["../../src/components/CrudButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CrudButton.d.ts","sourceRoot":"","sources":["../../src/components/CrudButton.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAI9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,IAAI,CACxD,iBAAiB,CAAC,CAAC,CAAC,EACpB,UAAU,CACX;IACC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,iBAAS,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,EAC/B,YAAmB,EACnB,IAAI,EACJ,QAAgB,EAChB,QAAQ,EACR,GAAG,iBAAiB,EACrB,EAAE,eAAe,CAAC,CAAC,CAAC,2CAYpB;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as o,jsxs as B}from"react/jsx-runtime";import{useMemo as g}from"react";import{Trash2 as G}from"lucide-react";import{Card as H,Stack as D,Text as V,ActionButton as J}from"@donotdev/components";import{useTranslation as I,getListCardFieldNames as K}from"@donotdev/core";import{formatValue as h}from"./DisplayFieldRenderer";import{translateFieldLabel as O}from"../forms/utils/translateFieldLabel";import{DisplayThumbnail as L}from"./DisplayThumbnail";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 N({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,T=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(L,{pictures:n,alt:String(T),aspectRatio:"16/9"},l)}return B("div",{children:[o(V,{level:"small",variant:"muted",children:O(l,i,a)}),o(V,{children:h(e[l],i,a,{compact:!0})})]},l)}).filter(Boolean);return r.length>0?o(D,{direction:"column",gap:"tight",children:r}):null},[e,t.fields,A,T,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(L,{pictures:u,alt:"",aspectRatio:"1"},i)}const F=h(e[i],n,a,{compact:!0});return o("span",{children:F},i)});return o(D,{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(V,{level:"small",children:r.join(" \xB7 ")})},[e,t.fields,m,a]),E=Q(t).delete,k=o(H,{title:String(T??""),subtitle:M,content:P??void 0,footer:q,clickable:!!c,onClick:c?()=>c(e.id):void 0,elevated:R,className:z}),w=j||s?B("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?B("div",{style:{position:"relative",height:"100%"},children:[k,w]}):k}var W=N;export{N as CrudCard,W as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as a,jsxs as
|
|
1
|
+
"use client";import{jsx as a,jsxs as b,Fragment as ut}from"react/jsx-runtime";import{useState as k,useMemo as pt}from"react";import{X as Dt}from"lucide-react";import{Button as S,Calendar as St,FloatingLabel as ht,Sheet as T,Text as xt}from"@donotdev/components";import{formatDate as $t}from"@donotdev/core";function ft({label:h,fieldType:yt,value:l,onChange:x,tCrud:i,locale:j="en"}){const[w,g]=k(!1),[F,$]=k(null),E=pt(()=>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 $t(n,j)}catch{return t}},N=()=>{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"),o=`${n}-${d}-${r}`,s=new Date(t);s.setDate(s.getDate()-1);const y=s.getFullYear(),f=String(s.getMonth()+1).padStart(2,"0"),B=String(s.getDate()).padStart(2,"0"),H=`${y}-${f}-${B}`,m=new Date(t);m.setDate(m.getDate()+1);const I=m.getFullYear(),L=String(m.getMonth()+1).padStart(2,"0"),W=String(m.getDate()).padStart(2,"0"),X=`${I}-${L}-${W}`,c=new Date(t);c.setDate(c.getDate()-7);const q=c.getFullYear(),A=String(c.getMonth()+1).padStart(2,"0"),G=String(c.getDate()).padStart(2,"0"),J=`${q}-${A}-${G}`,u=new Date(t);u.setDate(u.getDate()-30);const K=u.getFullYear(),P=String(u.getMonth()+1).padStart(2,"0"),Q=String(u.getDate()).padStart(2,"0"),R=`${K}-${P}-${Q}`,p=new Date(t);p.setDate(p.getDate()+7);const U=p.getFullYear(),Z=String(p.getMonth()+1).padStart(2,"0"),_=String(p.getDate()).padStart(2,"0"),tt=`${U}-${Z}-${_}`,D=new Date(t);D.setDate(D.getDate()+30);const et=D.getFullYear(),at=String(D.getMonth()+1).padStart(2,"0"),nt=String(D.getDate()).padStart(2,"0"),rt=`${et}-${at}-${nt}`,M=new Date(t.getFullYear(),t.getMonth(),1),lt=M.getFullYear(),it=String(M.getMonth()+1).padStart(2,"0"),gt=String(M.getDate()).padStart(2,"0"),st=`${lt}-${it}-${gt}`,v=new Date(t.getFullYear(),t.getMonth()+1,0),dt=v.getFullYear(),ot=String(v.getMonth()+1).padStart(2,"0"),mt=String(v.getDate()).padStart(2,"0"),ct=`${dt}-${ot}-${mt}`;return{today:o,yesterday:H,tomorrow:X,last7Days:J,last30Days:R,next7Days:tt,next30Days:rt,thisMonthStart:st,thisMonthEnd:ct}},e=E,O=N(),z=!!(e?.min||e?.max),Y=t=>{const n=t==="start",d=n?e?.min:e?.max;return a("div",{style:{padding:"var(--gap-md)"},children:b("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-md)"},children:[a("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 o=O[r];return a(S,{variant:"outline",onClick:()=>{x({min:n?o:e?.min||"",max:n?e?.max||"":o}),g(!1)},children:i(`filter.${r}`,{defaultValue:r})},r)})}),a(St,{selected:d?new Date(d+"T00:00:00"):void 0,mode:"single",onSelect:r=>{if(!r)return;const o=r.getFullYear(),s=String(r.getMonth()+1).padStart(2,"0"),y=String(r.getDate()).padStart(2,"0"),f=`${o}-${s}-${y}`;x({min:n?f:e?.min||"",max:n?e?.max||"":f}),g(!1)},defaultMonth:d?new Date(d+"T00:00:00"):new Date}),a(S,{variant:"ghost",display:"compact",onClick:()=>{x({min:n?"":e?.min||"",max:n&&e?.max||""}),g(!1)},children:i("filter.clear",{defaultValue:"Clear"})})]})})},V=b(ut,{children:[a(T,{trigger:a(S,{variant:"ghost",onClick:()=>{$("start"),g(!0)},style:{flex:1},children:e?.min?C(e.min):i("filter.min",{defaultValue:"Min"})}),title:`${h} - ${i("filter.min",{defaultValue:"Min"})}`,open:w&&F==="start",onOpenChange:t=>{g(t),t||$(null)},children:Y("start")}),a(xt,{level:"small",variant:"muted",style:{display:"flex",alignItems:"center"},children:"\u2013"}),a(T,{trigger:a(S,{variant:"ghost",onClick:()=>{$("end"),g(!0)},style:{flex:1},children:e?.max?C(e.max):i("filter.max",{defaultValue:"Max"})}),title:`${h} - ${i("filter.max",{defaultValue:"Max"})}`,open:w&&F==="end",onOpenChange:t=>{g(t),t||$(null)},children:Y("end")}),a(S,{variant:"ghost",display:"compact",icon:a(Dt,{size:16}),onClick:()=>{x(void 0)},disabled:!z,"aria-label":i("filter.clear",{defaultValue:"Clear"})})]});return h?a(ht,{label:h,className:"dndev-range-input",children:V}):a("div",{className:"dndev-range-input",children:V})}export{ft as DateFilter};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FieldType, EntityField } from '@donotdev/core';
|
|
2
|
+
import type { DisplayFormatterOptions } from '../fieldTypeRegistry';
|
|
2
3
|
import type { ReactElement } from 'react';
|
|
3
4
|
export interface DisplayFieldRendererProps<T extends FieldType = FieldType> {
|
|
4
5
|
/** Field identifier */
|
|
@@ -21,10 +22,7 @@ export interface DisplayFieldRendererProps<T extends FieldType = FieldType> {
|
|
|
21
22
|
* @param options.asString - Prefer string output when possible (e.g. for price in text placeholders)
|
|
22
23
|
* @returns Formatted value as string or ReactElement
|
|
23
24
|
*/
|
|
24
|
-
export declare function formatValue(value: any, config: EntityField, t: (key: string, options?: Record<string, any>) => string, options?:
|
|
25
|
-
compact?: boolean;
|
|
26
|
-
asString?: boolean;
|
|
27
|
-
}): string | ReactElement;
|
|
25
|
+
export declare function formatValue(value: any, config: EntityField, t: (key: string, options?: Record<string, any>) => string, options?: DisplayFormatterOptions): string | ReactElement;
|
|
28
26
|
/**
|
|
29
27
|
* DisplayFieldRenderer - Renders a field value as read-only display
|
|
30
28
|
*
|
|
@@ -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;
|
|
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;AAI7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,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,CA0DvB;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
|
|
1
|
+
"use client";import{jsx as r,jsxs as s}from"react/jsx-runtime";import{Text as a,Stack as c}from"@donotdev/components";import{handleError as d}from"@donotdev/core";import{translateFieldLabel as u}from"../forms/utils";import{getDisplayFormatter as y}from"../fieldTypeRegistry";function m(t,e,o,n){const i=n?.compact??!1;if(t==null||t==="")return i?r("span",{style:{color:"var(--muted-foreground)"},children:"\u2014"}):r(a,{variant:"muted",children:"\u2014"});const l=y(e.type);if(l)try{return l(t,e,o,n)}catch(f){return d(f,{userMessage:`Error formatting field "${e.label||e.name}"`,context:{fieldType:e.type,fieldName:e.label||"unknown",operation:"display_format"},severity:"warning"}),i?r("span",{style:{color:"var(--muted-foreground)"},children:String(t)}):r(a,{variant:"muted",children:String(t)})}return d(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"}),i?r("span",{style:{color:"var(--muted-foreground)"},children:String(t)}):r(a,{variant:"muted",children:String(t)})}function p({name:t,config:e,value:o,t:n}){const i=m(o,e,n,{compact:!1}),l=u(t,e,n);return s(c,{direction:"row",align:"baseline",style:{marginBottom:"var(--gap-sm)",padding:"var(--gap-sm)",minHeight:"38px",alignItems:"center"},children:[s(a,{variant:"muted",style:{fontSize:"var(--font-size-sm)",fontWeight:500,minWidth:"fit-content",flexShrink:0},children:[l,":"]}),r("div",{style:{flex:1,display:"flex",alignItems:"center"},children:typeof i=="string"?r(a,{children:i}):i})]})}var g=p;export{p as DisplayFieldRenderer,g as default,m as formatValue};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityFilters.d.ts","sourceRoot":"","sources":["../../src/components/EntityFilters.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EntityFilters.d.ts","sourceRoot":"","sources":["../../src/components/EntityFilters.tsx"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAW7C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,kBAAkB,CACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IACrE,EAAE,EAAE,MAAM,CAAC;CACZ;IAED,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IAEf,oFAAoF;IACpF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,sFAAsF;IACtF,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAE/B,8GAA8G;IAC9G,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IACrE,EAAE,EAAE,MAAM,CAAC;CACZ,EACD,EACA,MAAM,EACN,IAAI,EAAE,QAAQ,EACd,cAAc,EACd,OAAkB,GACnB,EAAE,kBAAkB,CAAC,CAAC,CAAC,kDAwpBvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as f,jsxs as B}from"react/jsx-runtime";import{useMemo as M}from"react";import{FilterX as U}from"lucide-react";import{Button as W,Combobox as Z,Grid as Y,Rating as ee,RangeInput as te,Slider as ae,Stack as ie}from"@donotdev/components";import{DateFilter as le}from"./DateFilter";import{useTranslation as $,handleError as I}from"@donotdev/core";import{translateFieldLabel as ne,translateLabel as L}from"../forms/utils";import{getFilterType as P,isFilterable as re}from"../fieldTypeRegistry";import{useCrudFilters as se}from"../hooks/useCrudFilters";import{useCrudCardList as oe}from"../useCrudCardList";import{matchesFilter as me}from"../utils/matchesFilter";import{matchesFilter as de}from"../utils/matchesFilter";function fe({entity:d,data:A,fieldsToFilter:T,variant:k="inline"}){const R=k==="sidebar",{t:p,i18n:z}=$("crud"),{t:j}=$([d.namespace,"crud"]),G=z?.language||"en",{data:X}=oe(d,{enabled:!A}),c=A??(X?.items||[]),{filters:b,setFilters:_}=se({collection:d.collection}),g=M(()=>(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]),D=M(()=>{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]=c;return}a[t]=c.filter(i=>Object.entries(o).every(([m,h])=>{const F=i[m],x=d.fields[m]?.type||"text";return me(F,h,x)}))}),a},[c,b,d.fields,g]),q=M(()=>{const a={};return g.forEach(t=>{const o=d.fields[t];if(!o)return;const i=o.type||"text",m=P(i);if(!m){I(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=c.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=c.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()))),w=new Date(Math.max(...n.map(C=>C.getTime()))),V=l.toISOString().split("T")[0],v=w.toISOString().split("T")[0];a[t]={min:V||"",max:v||""}}}}),a},[c,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;_(o)},H=()=>{_({})},S=M(()=>g.length===0?null:g.map(a=>{const t=d.fields[a];if(!t)return null;const o=ne(a,t,j),i=t.type||"text",m=P(i);if(!m)return I(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 f("div",{style:{gridColumn:"span 2"},children:f(ee,{value:s,max:r,"aria-label":o,onChange:e=>{y(a,e===s?void 0:String(e))}})},a)}if(F){const r=q[a],s=r?.min??0,e=r?.max??100,u=l.min?Number(l.min):s,N=l.max?Number(l.max):e;return B(ie,{gap:"tight",style:{gridColumn:"span 2"},children:[f(te,{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:(O,Q)=>{y(a,{min:O,max:Q})},onClear:()=>y(a,void 0)}),f(ae,{value:[u,N],min:s,max:e,step:1,onValueChange:O=>{y(a,{min:String(O[0]),max:String(O[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 f("div",{style:{gridColumn:"span 2",gridRow:R?void 0:"span 1"},children:f(le,{label:o,fieldType:r,value:s,locale:G,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 w=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():[]:[],V=D[a]||c,v=new Set,C=m==="address";V.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(w.length>0){const r=[],s=[];w.forEach(e=>{const u=typeof e=="string"?e:e.value,N=typeof e=="string"?e:e.label;v.has(u)?r.push({value:u,label:N}):s.push({value:u,label:N})}),r.sort((e,u)=>e.label.localeCompare(u.label)),s.sort((e,u)=>e.label.localeCompare(u.label)),r.forEach(e=>{E.push({value:e.value,label:L(e.label,j),disabled:!1})}),s.forEach(e=>{E.push({value:e.value,label:L(e.label,j),disabled:!0})})}else Array.from(v).sort().slice(0,100).forEach(r=>{E.push({value:r,label:r})});return f("div",{style:{gridColumn:"span 2",gridRow:"span 1"},children:f(Z,{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,c,b,j,p,D]);if(!S||S.length===0)return null;const J=S.filter(Boolean),K=Object.keys(b).length>0;return B(Y,{cols:k==="sidebar"?2:[2,4,6,8],children:[J,f(W,{variant:"outline",icon:f(U,{size:18}),onClick:H,disabled:!K,style:{gridColumn:"1 / -1",gridRow:"span 1"},children:p("filter.clear",{defaultValue:"Clear Filters"})})]})}export{fe as EntityFilters,de as matchesFilter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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";import"../builtinFieldTypes";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,m=p(x),g=v.getUncontrolledComponent(e.type);return g?t(g,{name:o,label:e.label||o,value:f,onChange:m,error:c,t:r,config:e,...e.options}):t(w,{label:e.label||o,value:f,onChange:m,error:c||void 0,...e.options})}var E=h;export{h as FormFieldRenderer,E as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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 F}from"@donotdev/components";import{useTranslation as I}from"@donotdev/core";const L=({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}=I("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)}},B={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(F,{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 A=L;export{A as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as n}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{AddressFieldComponent as p}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(f,{name:e,control:s,rules:o?u(o):void 0,render:({field:i})=>n(p,{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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as l}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{DateFieldComponent as p}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(f,{name:e,control:n,rules:o?C(o):void 0,render:({field:r})=>l(p,{...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 +1 @@
|
|
|
1
|
-
"use client";import{jsxs as
|
|
1
|
+
"use client";import{jsxs as n,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 R}from"../../../FieldRegistry";import{convertValidationRules as j}from"../types";function A(s){switch(s){case"number":return 0;case"boolean":return!1;default:return""}}function I(s){const{control:d,errors:h,fieldConfig:c,t:r}=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=R(),z=()=>{if(o.length===0)return;const a={};for(const t of o)a[t.name]=A(t.type);C(a)};return o.length===0?n("div",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:[r(f),": no sub-fields configured"]}):n("div",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-sm)"},children:[n("div",{style:{display:"flex",alignItems:"center",gap:"var(--gap-sm)"},children:[n("span",{style:{fontSize:"var(--font-size-sm)",fontWeight:"var(--font-weight-medium)"},children:[r(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":r(f)+" \u2014 add"})]}),b.map((a,t)=>n("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:r})},e.name):i("div",{style:{flex:l==="row"?1:void 0},children:i(D,{name:u,control:d,rules:e.validation?j(e.validation):void 0,render:({field:p})=>n("label",{style:{display:"flex",flexDirection:"column",gap:"var(--gap-tight)"},children:[i("span",{style:{fontSize:"var(--font-size-xs)"},children:r(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{I as ControlledFieldArrayField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as a}from"react/jsx-runtime";import{Controller as
|
|
1
|
+
"use client";import{jsx as a}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:t,fieldConfig:s,t:m}=l,{name:r,label:d,validation:o}=s;return a(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 a(f,{label:m(d),value:e.value||{},onChange:u,error:!!t[r],helperText:t[r]?.message,required:o?.required})}})}export{C as ControlledMapField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as t}from"react/jsx-runtime";import{Controller as
|
|
1
|
+
"use client";import{jsx as t}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 g(n){const{control:l,errors:v,fieldConfig:i,t:s}=n,{name:u,label:m,validation:r,options:c={}}=i;return t(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 a=JSON.parse(o.target.value);e.onChange(Array.isArray(a)?a:[])}catch{e.onChange([])}};return t(f,{label:s(m),value:Array.isArray(e.value)?e.value:[],onChange:d,required:r?.required,className:c.className})}})}export{g as ControlledMultiInputField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as t}from"react/jsx-runtime";import{Controller as u}from"react-hook-form";import{RichTextComponent as
|
|
1
|
+
"use client";import{jsx as t}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(n){const{control:i,errors:r,fieldConfig:s,t:m,placeholder:c}=n,{name:e,label:d,validation:o,options:l={}}=s;return t(u,{name:e,control:i,rules:o?h(o):void 0,render:({field:a})=>t(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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as n}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{TimestampFieldComponent as u}from"../../form/fields";import{convertValidationRules as f}from"../types";function c(t){const{control:a,errors:l,fieldConfig:i,t:m}=t,{name:e,label:s,validation:r}=i;return n(p,{name:e,control:a,rules:r?f(r):void 0,render:({field:o})=>n(u,{...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 +1 @@
|
|
|
1
|
-
import{ControlledAddressField as
|
|
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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as l}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{DocumentFieldComponent as f}from"../../form/fields";import{convertValidationRules as c}from"../types";function g(i){const{control:m,errors:r,fieldConfig:n,t:s}=i,{name:e,label:u,validation:o}=n,t=n.options||{};return l(p,{name:e,control:m,rules:o?c(o):void 0,render:({field:a})=>l(f,{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:t.maxSize,storagePath:t.storagePath})})}export{g as ControlledDocumentField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as n}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(t){const{control:m,errors:r,fieldConfig:l,t:s}=t,{name:e,label:u,validation:o}=l,a=l.options||{};return n(p,{name:e,control:m,rules:o?c(o):void 0,render:({field:i})=>n(f,{name:e,label:s(u),value:i.value??null,onChange:d=>i.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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as n}from"react/jsx-runtime";import{Controller as p}from"react-hook-form";import{DocumentFieldComponent as v}from"../../form/fields";import{convertValidationRules as f}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(p,{name:r,control:m,rules:o?f(o):void 0,render:({field:e})=>{const d=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return n(v,{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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as i}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{FileFieldComponent as v}from"../../form/fields";import{convertValidationRules as x}from"../types";function c(n){const{control:s,errors:a,fieldConfig:t,t:m}=n,{name:r,label:u,validation:o}=t,l=t.options||{};return i(f,{name:r,control:s,rules:o?x(o):void 0,render:({field:e})=>{const d=Array.isArray(e.value)?e.value:e.value?[e.value]:null;return i(v,{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{c as ControlledMultiFileField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as t}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{ImageFieldComponent as p}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(f,{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(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.fieldSpecific?.storagePath})}})}export{v as ControlledMultiImageField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ControlledDocumentField as l}from"./ControlledDocumentField";import{ControlledFileField as
|
|
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 +1 @@
|
|
|
1
|
-
import{convertValidationRules as
|
|
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 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as n}from"react/jsx-runtime";import{Controller as m}from"react-hook-form";import{CheckboxFieldComponent as f}from"../../form/fields";import{convertValidationRules as u}from"../types";function C(t){const{control:l,errors:p,fieldConfig:i,t:a}=t,{name:d,label:e,validation:o}=i,c=typeof e=="string"?a(e):e;return n(m,{name:d,control:l,rules:o?u(o):void 0,render:({field:r})=>n(f,{label:c,checked:!!r.value,onChange:s=>r.onChange(s.target.checked),required:o?.required})})}export{C as ControlledCheckboxField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as u}from"react/jsx-runtime";import{Controller as g}from"react-hook-form";import{CurrencyFieldComponent as h}from"../../form/fields";import{convertValidationRules as y}from"../types";function N(c){const{control:s,errors:n,fieldConfig:a,t:d,placeholder:m}=c,{name:o,label:p,validation:l}=a,t=(a.options||{}).fieldSpecific;return u(g,{name:o,control:s,rules:l?y(l):void 0,render:({field:e})=>{const f=v=>{const r=v.target.value;if(r==null||r===""){e.onChange(null);return}const i=typeof r=="number"?r/100:parseFloat(String(r))/100;isNaN(i)?e.onChange(null):e.onChange(i)},C=e.value!=null&&!isNaN(e.value)?Math.round(e.value*100):void 0;return u(h,{label:d(p),value:C,onChange:f,currency:t?.currency||"EUR",locale:t?.locale,error:!!n[o],helperText:n[o]?.message,required:l?.required,placeholder:m})}})}export{N as ControlledCurrencyField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as a}from"react/jsx-runtime";import{Controller as
|
|
1
|
+
"use client";import{jsx as a}from"react/jsx-runtime";import{Controller as f}from"react-hook-form";import{DurationFieldComponent as p}from"../../form/fields";import{convertValidationRules as c}from"../types";function C(s){const{control:d,errors:n,fieldConfig:l,t}=s,{name:e,label:m,validation:o}=l,r=(l.options||{}).fieldSpecific;return a(f,{name:e,control:d,rules:o?c(o):void 0,render:({field:i})=>a(p,{label:t(m),value:i.value??0,onChange:u=>i.onChange(u),error:!!n[e],helperText:n[e]?.message,required:o?.required,disabled:i.disabled,min:r?.min??0,max:r?.max??480,step:r?.step??5,t})})}export{C as ControlledDurationField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as o}from"react/jsx-runtime";import{Controller as C}from"react-hook-form";import{GdprConsentFieldComponent as u}from"../../form/fields";import{convertValidationRules as h}from"../types";function v(i){const{control:a,errors:y,fieldConfig:l}=i,{name:s,validation:n,options:d={}}=l,r=d.fieldSpecific,c=r?.privacyPolicyPath||"/legal/privacy",p=r?.termsPath||"/legal/terms";return o(C,{name:s,control:a,rules:n?h(n):void 0,render:({field:t})=>{const e=t.value,m=typeof e=="object"&&e!==null?!!e.gdprConsent:!!e;return o(u,{checked:m,onChange:g=>{if(g.target.checked){const f=new Date().toISOString().split("T")[0];t.onChange({gdprConsent:!0,gdprConsentDate:new Date().toISOString(),gdprConsentVersion:f})}else t.onChange(!1)},required:n?.required,privacyPolicyPath:c,termsPath:p})}})}export{v as ControlledGdprConsentField};
|