1.34.16 • Published 1 month ago

@pagopa/selfcare-common-frontend v1.34.16

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

SelfCare's common components & features

This library contains utilities, components, decorators, custom hooks and features built for the selfcare project.

Localization

This libray has been built using react-i18next and string inside of it are also localizated. Actually the library contains the only "it" translation. The translations for the keys of the common components can be overwritten using the resources used during configuration. In order to configure it call the method configureI18n of the module locale/locale-utils which accept the following parameters: | Param | Type | Mandatory | Description | |-------|------|-----------|-------------| | resources | Y | { lang: string: any } | a map containing the language as key and the map containing the key/translated messages as value. These values overwrite common's component keys if desired | | defaultLanguage | N | string | as default it language |

Configuration

In order to use these components it's necessary to set the following keys of the CONFIG object imported from /config/env as first things inside the application:

KeyTypeDescriptionDefaultValue
URL_FE.LOGIN_GOOGLEstringThe url of the google login page/auth/google
URL_FE.LOGINstringThe url of the login page/auth/login
URL_FE.LOGOUTstringThe url of the logout page/auth/logout
URL_FE.ASSISTANCEstringThe url of the assistance page/assistenza
MOCKS.MOCK_USERbooleanIf the application should configure a logged mocked User usable in DEV environmentfalse
ANALYTICS.*See analitics feature
CONSENT.*See consent management feature

Components

Header

SelfCare Header component

PropTypeMandatoryDescription
withSecondHeaderYbooleanIf true, it will render an other toolbar under the Header
productsListNArrayProductEntityThe list of products in header. Default []
selectedPartyIdNThe party id selected
selectedProductIdNThe product id selected. Default selfcareProduct.id
partyListNArrayPartyEntityThe parties list. Default []
loggedUserYJwtUser | falseThe logged user or false if there is not a valid session
assistanceEmailNstringThe email to which the assistance button will ask to send an email, if the user is not logged in, otherwise it will be redirect to the assistance form
onSelectedProductN(product: ProductSwitchItem) => voidThe function invoked when the user click on a product
onSelectedPartyN(exitAction: () => void) => voidThe function invoked when the user click on a party from the switch
onExitN(exitAction: () => void) => voidThe function invoked when exiting from the application. As default it will just invoke the exitAction. Default exitAction => exitAction()
enableLoginNbooleanIf false, it will hide login/logout buttons. Default true
userActionsNArray <UserAction>The users actions inside the user dropdown. It's visible only if enableLogin and enableDropdown are true. Default []
enableDropdownNbooleanIf true the user dropdown in headerAccount component is visible. It's visible only if enableLogin is true. Default false
addSelfcareProductNbooleanIf true it concatenates selfcareProduct with productsList. Default true

Footer

SelfCare Footer component

PropTypeMandatoryDescription
loggedUserYbooleanThe logged user or false if there is not a valid session
onExitN(exitAction: () => void) => voidThe function invoked when exiting from the application. As default it will just invoke the exitAction. Default exitAction => exitAction()

CustomAvatar

Avatar to use to load Organization logo

PropTypeMandatoryDescription
idstringNThe id attribute added to the element
customSrcstringNThe logo src
customAltstringNThe alt text showed instead of the image
customWidthstringNLogo width
customHeightstringNLogo height
loadingbooleanNIf true it will not display the component

CustomPagination

Selfcare custom table available pages component

PropTypeMandatoryDescription
pagePageYThe actual page
sortstringNThe actual sort applied
onPageRequest(r: PageRequest) => voidYThe function to be invoked if the user change page

FilterModal

Modal used to show a list of values from which to choose a single value

PropTypeMandatoryDescription
openbooleanYIf the popup is to be displayed
handleCloseReact.MouseEventHandler<HTMLButtonElement>YThe function to be invoked when clicking on exit button or selecting a value
titlestringYThe popup title
filterModalConfigFilterModalConfig<any, any>NSee below
heightstringNThe popup height
minHeightstringNThe popup minHeight

FilterModalConfig fields: | Field | Type | Mandatory | Description | |-------|------|-----------|-------------| | data | Array<T> | Y | The list of values between to which choose | | getLabel | (e: T) => string | Y | A function that will select the label to show | | getValue | (e: T) => string | Y | A function that will select the value to return when selecting an item | | onFilterChange | (v: V) => void | Y | The function invoked when selecting a value |

SessionModal

Selfcare's popup

PropTypeMandatoryDescription
openbooleanYIf this component should be displayed or not
titlestringYThe title to show in the popup
messageReact.ReactNodeYThe body to show in the popup
onConfirmReact.MouseEventHandler<HTMLButtonElement>NIf defined, it will render a confirm button using this function as behavior
onConfirmEnabledbooleanNIf the confirm button should be enabled. Default true
onConfirmLabelstringNThe confirm label text
productEnvironmentsArray<{environment: string;url: string;}>NIntroduced to manage the presence of test environments in the products, if defined, it will render as many buttons as there are test environments for the product
handleCloseReact.MouseEventHandler<HTMLButtonElement>YThe function invoked when clicking on close button or in the showed X icon
handleExitReact.MouseEventHandler<HTMLButtonElement>NIf defined, it allow to set a different behavior when clicking on X icon
onCloseLabelstringNClose button text
heightstringNThe popup height
minHeightstringNThe popup minHeight
widthstringNThe popup width

TitleBox

Selfcare's page title

PropTypeMandatoryDescription
titlestringYThe title to show
subTitlestringNThe subtitle to show
mtTitlenumberNThe margin top of the title
mbTitlenumberNThe margin bottom of the title
mbSubTitlenumberNThe margin bottom of the subtitle
variantTitleVariantNThe variant of the Typografy used for the title
variantSubTitleVariantNThe variant of the Typografy used for the subtitle

Toast

Selfcare's toast

PropTypeMandatoryDescription
openbooleanYIf this component should be displayed or not
logoReact.ElementTypeNThe logo to be rendered. As default a confirm logo will be used
leftBorderColorstringNThe color used for the left border.
titlestringYThe toast title
messageReact.ReactNodeYThe toast body
onCloseToast()=>voidYThe function to be invoked when closing the toast
widthstringNThe toast width
wrappedbooleanNIf true, it will not position itself as fixed. Default false
bottomstringNIf not wrapped, the pixel from the bottom of the viewport where to place the toast. Default "64px"
rigthstringNIf not wrapped, the pixel from the right side of the viewport where to place the toast. Default "64px"

ToastWrapper

To stack multiple Toast component. Each Toast should have the prop wrapped setted to true

PropTypeMandatoryDescription
bottomstringNThe pixel from the bottom of the viewport where to place the toast. Default "64px"
rigthstringNThe pixel from the right side of the viewport where to place the toast. Default "64px"

Ending Page

Selfcare's ending page

PropTypeMandatoryDescription
iconReact.ReactElementNThe ending page icon
titlestringYThe ending page title
descriptionReact.ReactNodeYThe ending page description
buttonLabelstringNThe ending page button label if any
onButtonClick() => voidNif defined it will show a button that will performe this action on click
variantTitle('button''caption''h1''h2''h3''h4''h5''h6''inherit''subtitle1''subtitle2''body1''body2''overline'undefined;)NSet the variant of the title
variantDescription('button''caption''h1''h2''h3''h4''h5''h6''inherit''subtitle1''subtitle2''body1''body2''overline'undefined;)NSet the variant of the description

NavigationBar

Selfcare's navigation bar

PropTypeMandatoryDescription
pathsArray<NavigationPath>YThe array which describe the navigation structure to display

NavigationPath's fields: | field | Type | Mandatory | Description | |------|------|-----------|-------------| | description | string | Y | The text displayed | | onClick | () => void | N | If defined, it will represent the function executed when clicking on the element. Moreover it will be displayed in bold |

LoadingOverlayComponent

A component which render an overlay loading

PropTypeMandatoryDescription
openbooleanYif show the loading overlay or not

NavigationPath's fields: | field | Type | Mandatory | Description | |------|------|-----------|-------------| | description | string | Y | The text displayed | | onClick | () => void | N | If defined, it will represent the function executed when clicking on the element. Moreover it will be displayed in bold |

Utilities

api-utils

onRedirectToLogin: (store: EnhancedStore) => void

To show an error popup to inform of the not valid session

buildFetchApi = (timeoutMs: number = 300000) => fetch

Return the implementation of fetch configured with a timeout

extractResponse <R>(response: t.Validation<TypeofApiResponse<any>>, successHttpStatus: number, onRedirectToLogin: () => void, notValidTokenHttpStatus: number | null = 401, notAuthorizedTokenHttpStatus: number | null = 403, emptyResponseHttpStatus: number | null = 404): Promise<R>

Extract the response of a @pagopa/openapi-codegen-ts generated client rest invocation having status code successHttpStatus. If notValidTokenHttpStatus is not null and the returned status is equal to notValidTokenHttpStatus, it will call the onRedirectToLogin function and will schedule the redirect towards logout path. If notAuthorizedTokenHttpStatus is not null and the returned status is equal to notAuthorizedTokenHttpStatus, it will throw an Error with message "Operation not allowed". If emptyResponseHttpStatus is not null and the returned status is equal to emptyResponseHttpStatus, it will return a promise that resolve to null value. Other statuses will return will throw a generic error.

constants

roleLabels: { key in UserRole: { shortLabel: string; longLabel: string } }

The short and long labels used for the roles of selfcare's projects

routes-utils

resolvePathVariables: (path: string, pathVariables: { key: string: string }): string

It will resolve the path variables in path using the provided map

storage-utils

storageDelete: (key: string, local?: boolean) => void

It will delete a key from the session storage. If local is true, it will use the local session storage instead.

storageWrite: (key: string, value: StorageValue, type: StorageValueType, local?: boolean) => void

It will store a key/value pair in the session storage. If local is true, it will use the local session storage instead.

storageRead: (key: string, type: StorageValueType, local?: boolean) => void

It will read a key from the session storage. If local is true, it will use the local session storage instead.

storageOpsBuilder(key: string, type: StorageValueType, local: boolean): StorageOps

It will build an object containing a complete set of operation to perform on the same key.

utils

formatDateAsLongString: (date: Date) => string

It will return a string representing the provided date in the italian format gg mmm aaaa

fixSwagger20ArraySchemaDef.js

An utility script to use when generating the stub through @pagopa/openapi-codegen-ts in order to handle the REST api whose operations returns an array of objects

storage

storageTokenOps

An object containing a complete set of operation on the storage regarding the key used to store in the storage the loggedUser token in selfcare projects.

storageUserOps

An object containing a complete set of operation on the storage regarding the key used to store in the storage the loggedUser in selfcare projects.

parseJwt

Decode and then convert the jwt into a JWTUser object

isExpiredToken

Determines whether the token has expired

Decorators

withLogin

This feature is based on react-redux library and require to register the reducer build in userSlice into the application's redux store. This decorator has to be applied to components whose acces require an active session. Accessing to the components decorated with it without a session will brought to the login page. It's possible to modify the login path changing the value in CONFIG.URL_FE.LOGIN inside the index.tsx file

withRetrievedValue

Decorator to retrieve a value and serve it once ready to the decorated component, moreover it will provide the decorated component a function to re-execute the retrieve method.

Using it together with useReduxCachedValue will allow to build a component which will use centralized and cached data (the reload function in this case will call again the function that will retrieve cached data).

See withRetrievedValue.test.tsx file for an example.

Given the following type parameters:

  • ENTITY_TYPE extends Record<string, any>,
  • PROP_NAME extends string,
  • PROPS extends Record<PROP_NAME, ENTITY_TYPE>

The arguments to provide to the decorator are the following:

PropTypeMandatoryDescription
propEntityNamePROP_NAMEYThe name of the prop to which serve the value when available
getRetrieverService() => () => Promise<ENTITY_TYPE>YA function that will return an other function to retrieve the expected value. This for allow the use of custom hook
WrappedComponentReact.ComponentType<PROPS>YThe component to decore
onError(appError: AppError) => voidNWhat to do in case of error. As default, it will use the feature ErrorBoundary
onLoadingReactNodeNA component to show while waiting for the value

Custom Hooks

useFakePagination

Custom hook used to simulate paginated resources when the external service doesn't implement it, caching values when filter doesn't change and serving them a page at time. Cached values are stored using useRef, so they are local to the component using this hook. The sorting actually is applied using string representation

useReduxCachedValue

See useReduxCachedValueParametricRetrieverTranscoded when there is not RETRIEVER_ARGS and RETRIEVED_VALUE === RETRIEVER_ARGS

useReduxCachedValueParametricRetriever

See useReduxCachedValueParametricRetrieverTranscoded when RETRIEVED_VALUE === RETRIEVER_ARGS

useReduxCachedValueTranscoded

See useReduxCachedValueParametricRetrieverTranscoded when there is not RETRIEVER_ARGS

useReduxCachedValueParametricRetrieverTranscoded

It will return a method that will call the retrieverService only when there are not storing values, or a condition on them is not more verified. See useReduxCachedValue.test.tsx file for an example.

Given the following type parametes:

  • RETRIEVED_VALUE the type desired
  • STORED_VALUE the type stored

The arguments to provide to the custom hook are the following:

PropTypeMandatoryDescription
entitystringYThe name of the entity, used just for logging purpose
retrieverService(retrieverServiceArgs: RETRIEVER_ARGS) => Promise<RETRIEVED_VALUE>YThe service that will retrieve the value
reduxSelector(state: any) => STORED_VALUEundefinedYThe selector to read the value from redux
reduxSetterAction(value: RETRIEVED_VALUE, retrieverServiceArgs: RETRIEVER_ARGS) => PayloadAction<STORED_VALUE>YThe action to store the value
selectedValue2RetrievedValue(value: STORED_VALUE, args: RETRIEVER_ARGS) => RETRIEVED_VALUEYA function called to transform STORED_VALUE into RETRIEVED_VALUE and called when hitting the cache
selectedValuePredicate2Retrieve(value: STORED_VALUE, retrieverServiceArgs: RETRIEVER_ARGS) => booleanNAn optional predicate evaluated when reduxSelector returned some value in order to compare it against the retrieverServiceArgs and evaluate if retrieverService should be called again
alwaysRetrievebooleanNIf true, it will always retrieve and store the new value

Features

LoadingOverlay

This feature is based on react-redux library and require to register the reducer build in appStateSlice into the application's redux store. It allows to draw a loader when an async task to wait is running.

To use this feature you have to put LoadingOverlay in your App as a child of a redux Provider component. In order to register the start of an async task you have to use the custom hook useLoading passing the id of the task to await, which will return a setter function used to start and end the loading behavior.

ErrorBoundary

This feature is based on react-redux library and require to register the reducer build in appStateSlice into the application's redux store. It allows to dispatch errors in order to display a warning or the error page to the user. Errors dispatched will be notified using errorService

To use this feature you have to put ErrorBOundary in your App as a child of a redux Provider component. In order to dispatch an error you have to use the custom hook useErrorDispatcher which will return a fuction to be used to dispatch the error.

The error to be submitted has type AppError which has the following fields:

FieldTypeMandatoryDescription
idstringYThe identifier used to recognize the error: it cannot be possible to have the same error id at the same time
errorErrorYThe Error thrown
errorInfoErrorInfoN
blockingbooleanYIf true, this error will show the error page, not allowing the user to do anything, otherwise it will show a closable popup
techDescriptionstringYA description of the error to send when notifying the error
displayableTitlestringNA text to show as title of the popup when a not blocking error occurs
displayableDescriptionReact.ReactNodeNA text to show as body of the popup when a not blocking error occurs
onRetry() => voidNIf defined, in case of not blocking error, it will render a retry button which will execute this function
onClose() => voidNIf defined, in case of not blocking error, it will be executed when closing the popup
toNotifybooleanYIf true, it will notify the error
componentstringNCan render a SessionModal or Toast component
autoclosablestringNIf component === 'Toast'. The notify will be autoclosed using this configuration, as default timer. If none, it will not be closed automatically. If timer, it will be closed after autocloseMilliseconds milliseconds
autocloseMillisecondsbooleanNIf component === 'Toast' and autoclosable === 'timer'. The millisecond after which close the notify. As default 2000
widthstringNThe SessionModal or Toast width

The error will be notified as a GENERIC_ERROR through the analytcs feature

UserNotifyHandle

This feature is based on react-redux library and require to register the reducer build in appStateSlice into the application's redux store. It allows to dispatch User Notifies in order to display a pop up or a toast notification.

To use this feature you have to put UserNotifyHandle in your App as a child of a redux Provider component. In order to dispatch a User Notify, you have to use the custom hook useUserNotify which will return a fuction to be used to dispatch the User Notify.

The user notify to be submitted has type UserNotify which has the following fields:

FieldTypeMandatoryDescription
idstringYThe identifier used to recognize the user notify: it cannot be possible to have the same error id at the same time
titlestringY/ The title to show in the popup or toast
messageReact.ReactNodeYThe body to show in the popup or toast
logoReact.ElementTypeNIf component === 'Toast'. The logo to be rendered. As default a confirm logo will be used
leftBorderColorstringNIf component === 'Toast'. The color used for the left border
onConfirm() => voidNIf component === 'SessionModal'. If defined, it will render a confirm button which will execute this function
confirmLabelstringNIf component === 'SessionModal'. If present, this string will rappresent the confirm button label
onClose() => voidNIf defined, it will be executed when closing the popup
closeLabelstringNIf component === 'SessionModal'. The close button label
componentstringNCan render a SessionModal or Toast component
autoclosablestringNIf component === 'Toast'. The notify will be autoclosed using this configuration, as default timer. If none, it will not be closed automatically. If timer, it will be closed after autocloseMilliseconds milliseconds
autocloseMillisecondsbooleanNIf component === 'Toast' and autoclosable === 'timer'. The millisecond after which close the notify. As default 10000
widthstringNThe SessionModal or Toast width

UnloadEventHandler

This feature is based on react-redux library and require to register the reducer build in appStateSlice into the application's redux store. It allows to intercept when the user try to exit from the current page and ask him if he wants to continue or not.

To use this feature you have to put UnloadEventHandler in your App as a child of a redux Provider component. In order to use this feature you have to use the custom hook useUnloadEventInterceptor, which will return an object having the following keys: 1. registerUnloadEvent: an arrow function which takes two optional parameters to customize the title and the description of the pop-up opened when invoking the exitAction function (see below) and enable the functionality. 2. unregisterUnloadEvent: an arrow function to call in order to disable this functionality.

If you wont to enable immediately this functionality when invoking the custom hook you can use the hook useUnloadEventInterceptorAndActivate, which will enable the functionality and will disable it when unmounting the component.

In order to show a custom pop-up when the user trigger an exit action you have to use the custom hook useUnloadEventOnExit which will return an arrow function to invoke instead of the exit action passing to it the exitAction itself.

When the exitAction is the Logout you can use the custom hook useUnloadEventLogout which is the customization of the useUnloadEventOnExit using the logout as an exit action.

Analytics

This feature allow to track the application events through an analytics tool. The actual version of the library make use of mixpanel tool to handle the tracking.

In order to start the analytics you have to call the initAnalytics method imported from the service/analyticsService module, otherwise this feature will be ignored

This feature can be configured with the following keys of the CONFIG object (each key has the ANALYTCS. prefix):

KeyTypeDescriptionDefaultValue
ENABLEDbooleanIf disabled, it will do nothing (except for event having name GENERIC_ERROR, if disabled, these events will be printed through console.error)false
MOCKbooleanIf true, it will print the event through the console.log functionfalse
DEBUGbooleanIf the mixpanel's debug feature should be enabledfalse
TOKENstringThe token to use when sending event data
API_HOSTstringThe url where to send mixpanel eventshttps://api-eu.mixpanel.com
PERSISTENCEstringWhere to store session data, possible values are cookie or localStoragelocalStorage
LOG_IPbooleanIf the ip should be sentfalse
LOG_IPbooleanIf the ip should be sentfalse
PROPERTY_BLACKLISTArray<string>If the ip should be sent"$current_url", "$initial_referrer", "$referrer"
ADDITIONAL_PROPERTIES{key: string: string}An object containing a fixed set of properties to send every time, overridden if the actual event will report the same properties{}
ADDITIONAL_PROPERTIES_IMPORTANT{key: string: string}As ADDITIONAL_PROPERTIES, but these properties will take the precedence overriding events conflicting properties{}

In order track an event (once the initAnalytics method has been invoked) you have to call the trackEvent(event_name: string, properties?: any, callback?: () => void)=> void method where:

  • event_name: the name of the event
  • properties: the additional payload sent with the event
  • callback: an action taken when the track has completed (If the action taken immediately after the track is an exit action from the application, it's better to use this callback to perform the exit, in order to give to mixPanel the time to send the event)

Consent management

This feature allows the automatic enabling of the analytics feature only when the user accept to send that data.

The tool used is OneTrust, and in order to be able to use it, you have: 1. to put the script tag obtained when registering to the service inside the head section of your index.html file. 2. import the consentManagementConfigure.ts script inside your index.ts file (after the configuration of the common library)

KeyTypeDescriptionDefaultValue
COOKIE_GROUP_ANALYTICSstringThe cookie group configured for the analytics tool. MixPanel's cookies are configured as default by OneTrust with C0004 group, or as Targeting CookiesC0004
1.34.15

1 month ago

1.34.16

1 month ago

1.34.14

3 months ago

1.34.13

4 months ago

1.34.12

5 months ago

1.29.0

10 months ago

1.32.0

10 months ago

1.34.2

9 months ago

1.34.3

9 months ago

1.34.0

10 months ago

1.34.1

10 months ago

1.34.6

7 months ago

1.34.7

7 months ago

1.34.4

7 months ago

1.34.10

7 months ago

1.34.8

7 months ago

1.34.9

7 months ago

1.34.11

7 months ago

1.33.0

10 months ago

1.35.0

10 months ago

1.27.0

10 months ago

1.30.0

10 months ago

1.28.0

10 months ago

1.31.0

10 months ago

1.25.0

10 months ago

1.26.0

10 months ago

1.23.0

11 months ago

1.24.0

11 months ago

1.18.0

1 year ago

1.21.0

1 year ago

1.19.0

1 year ago

1.22.0

1 year ago

1.16.1

1 year ago

1.17.0

1 year ago

1.20.0

1 year ago

1.16.0

1 year ago

1.14.0

1 year ago

1.15.0

1 year ago

1.13.6

1 year ago

1.13.5

1 year ago

1.13.9

1 year ago

1.13.8

1 year ago

1.13.10

1 year ago

1.13.7

1 year ago

1.13.2

1 year ago

1.13.1

1 year ago

1.13.0

1 year ago

1.13.4

1 year ago

1.13.3

1 year ago

1.12.10

2 years ago

1.12.12

2 years ago

1.12.11

2 years ago

1.12.13

2 years ago

1.12.3

2 years ago

1.12.2

2 years ago

1.12.1

2 years ago

1.12.0

2 years ago

1.12.7

2 years ago

1.12.6

2 years ago

1.12.5

2 years ago

1.12.4

2 years ago

1.12.9

2 years ago

1.12.8

2 years ago

1.11.14

2 years ago

1.11.12

2 years ago

1.11.13

2 years ago

1.11.10

2 years ago

1.11.11

2 years ago

1.11.4

2 years ago

1.11.8

2 years ago

1.11.7

2 years ago

1.11.6

2 years ago

1.11.5

2 years ago

1.11.9

2 years ago

1.10.9

2 years ago

1.11.0

2 years ago

1.11.3

2 years ago

1.11.2

2 years ago

1.11.1

2 years ago

1.10.11

2 years ago

1.10.10

2 years ago

1.10.5

2 years ago

1.10.4

2 years ago

1.10.3

2 years ago

1.10.2

2 years ago

1.10.8

2 years ago

1.10.7

2 years ago

1.10.6

2 years ago

1.8.0

2 years ago

1.9.0

2 years ago

1.7.0

2 years ago

1.10.1

2 years ago

1.10.0

2 years ago

1.6.2

2 years ago

1.6.1

2 years ago

1.6.0

2 years ago

1.5.16

2 years ago

1.5.15

2 years ago

1.5.18

2 years ago

1.5.17

2 years ago

1.5.19

2 years ago

1.5.20

2 years ago

1.5.14

2 years ago

1.5.13

2 years ago

1.5.12

2 years ago

1.5.11

2 years ago

1.5.10

2 years ago

1.5.9

2 years ago

1.5.8

2 years ago

1.5.7

2 years ago

1.5.6

2 years ago

1.5.5

2 years ago

1.5.4

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago