mirror of
https://github.com/penpot/penpot.git
synced 2025-01-09 00:10:11 -05:00
✨ Improve multi-input initial value handling
And removes the hard coupling of invite-email from it
This commit is contained in:
parent
607e0c5c1d
commit
6eadea8485
4 changed files with 73 additions and 70 deletions
|
@ -420,14 +420,25 @@
|
||||||
(into [] (distinct) (conj coll item)))
|
(into [] (distinct) (conj coll item)))
|
||||||
|
|
||||||
(mf/defc multi-input
|
(mf/defc multi-input
|
||||||
[{:keys [form label class name trim valid-item-fn caution-item-fn on-submit invite-email] :as props}]
|
[{:keys [form label class name trim valid-item-fn caution-item-fn on-submit] :as props}]
|
||||||
(let [form (or form (mf/use-ctx form-ctx))
|
(let [form (or form (mf/use-ctx form-ctx))
|
||||||
input-name (get props :name)
|
input-name (get props :name)
|
||||||
touched? (get-in @form [:touched input-name])
|
touched? (get-in @form [:touched input-name])
|
||||||
error (get-in @form [:errors input-name])
|
error (get-in @form [:errors input-name])
|
||||||
focus? (mf/use-state false)
|
focus? (mf/use-state false)
|
||||||
|
|
||||||
items (mf/use-state [])
|
items (mf/use-state
|
||||||
|
(fn []
|
||||||
|
(let [initial (get-in @form [:data input-name])]
|
||||||
|
(if (or (vector? initial)
|
||||||
|
(set? initial))
|
||||||
|
(mapv (fn [val]
|
||||||
|
{:text val
|
||||||
|
:valid (valid-item-fn val)
|
||||||
|
:caution (caution-item-fn val)})
|
||||||
|
initial)
|
||||||
|
[]))))
|
||||||
|
|
||||||
value (mf/use-state "")
|
value (mf/use-state "")
|
||||||
result (hooks/use-equal-memo @items)
|
result (hooks/use-equal-memo @items)
|
||||||
|
|
||||||
|
@ -527,13 +538,8 @@
|
||||||
(let [val (cond-> @value trim str/trim)
|
(let [val (cond-> @value trim str/trim)
|
||||||
values (conj-dedup result {:text val :valid (valid-item-fn val)})
|
values (conj-dedup result {:text val :valid (valid-item-fn val)})
|
||||||
values (filterv #(:valid %) values)]
|
values (filterv #(:valid %) values)]
|
||||||
(update-form! values)))
|
|
||||||
|
|
||||||
(mf/with-effect []
|
(update-form! values)))
|
||||||
(when invite-email
|
|
||||||
(swap! items conj-dedup {:text (str/trim invite-email)
|
|
||||||
:valid (valid-item-fn invite-email)
|
|
||||||
:caution (caution-item-fn invite-email)})))
|
|
||||||
|
|
||||||
[:div {:class klass}
|
[:div {:class klass}
|
||||||
[:input {:id (name input-name)
|
[:input {:id (name input-name)
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
(assoc :project-id (uuid project-id)))))
|
(assoc :project-id (uuid project-id)))))
|
||||||
|
|
||||||
(mf/defc dashboard-content
|
(mf/defc dashboard-content
|
||||||
[{:keys [team projects project section search-term profile invite-email] :as props}]
|
[{:keys [team projects project section search-term profile] :as props}]
|
||||||
(let [container (mf/use-ref)
|
(let [container (mf/use-ref)
|
||||||
content-width (mf/use-state 0)
|
content-width (mf/use-state 0)
|
||||||
project-id (:id project)
|
project-id (:id project)
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
[:& libraries-page {:team team}]
|
[:& libraries-page {:team team}]
|
||||||
|
|
||||||
:dashboard-team-members
|
:dashboard-team-members
|
||||||
[:& team-members-page {:team team :profile profile :invite-email invite-email}]
|
[:& team-members-page {:team team :profile profile}]
|
||||||
|
|
||||||
:dashboard-team-invitations
|
:dashboard-team-invitations
|
||||||
[:& team-invitations-page {:team team}]
|
[:& team-invitations-page {:team team}]
|
||||||
|
@ -231,10 +231,7 @@
|
||||||
|
|
||||||
plugin-url (-> route :query-params :plugin)
|
plugin-url (-> route :query-params :plugin)
|
||||||
|
|
||||||
invite-email (-> route :query-params :invite-email)
|
|
||||||
|
|
||||||
team (mf/deref refs/team)
|
team (mf/deref refs/team)
|
||||||
|
|
||||||
projects (mf/deref refs/dashboard-projects)
|
projects (mf/deref refs/dashboard-projects)
|
||||||
project (get projects project-id)
|
project (get projects project-id)
|
||||||
|
|
||||||
|
@ -287,5 +284,4 @@
|
||||||
:project project
|
:project project
|
||||||
:section section
|
:section section
|
||||||
:search-term search-term
|
:search-term search-term
|
||||||
:team team
|
:team team}])])]]]))
|
||||||
:invite-email invite-email}])])]]]))
|
|
||||||
|
|
|
@ -59,13 +59,16 @@
|
||||||
|
|
||||||
(mf/defc header
|
(mf/defc header
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/props :obj}
|
||||||
[{:keys [section team invite-email]}]
|
[{:keys [section team]}]
|
||||||
(let [on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
|
(let [on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
|
||||||
on-nav-settings (mf/use-fn #(st/emit! (dd/go-to-team-settings)))
|
on-nav-settings (mf/use-fn #(st/emit! (dd/go-to-team-settings)))
|
||||||
on-nav-invitations (mf/use-fn #(st/emit! (dd/go-to-team-invitations)))
|
on-nav-invitations (mf/use-fn #(st/emit! (dd/go-to-team-invitations)))
|
||||||
on-nav-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks)))
|
on-nav-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks)))
|
||||||
|
|
||||||
|
route (mf/deref refs/route)
|
||||||
|
invite-email (-> route :query-params :invite-email)
|
||||||
|
|
||||||
members-section? (= section :dashboard-team-members)
|
members-section? (= section :dashboard-team-members)
|
||||||
settings-section? (= section :dashboard-team-settings)
|
settings-section? (= section :dashboard-team-settings)
|
||||||
invitations-section? (= section :dashboard-team-invitations)
|
invitations-section? (= section :dashboard-team-invitations)
|
||||||
|
@ -74,14 +77,14 @@
|
||||||
|
|
||||||
on-invite-member
|
on-invite-member
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps team)
|
(mf/deps team invite-email)
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (modal/show {:type :invite-members
|
(st/emit! (modal/show {:type :invite-members
|
||||||
:team team
|
:team team
|
||||||
:origin :team
|
:origin :team
|
||||||
:invite-email invite-email}))))]
|
:invite-email invite-email}))))]
|
||||||
|
|
||||||
(mf/with-effect []
|
(mf/with-effect [team invite-email]
|
||||||
(when invite-email
|
(when invite-email
|
||||||
(on-invite-member)))
|
(on-invite-member)))
|
||||||
|
|
||||||
|
@ -134,7 +137,7 @@
|
||||||
(mf/defc invite-members-modal
|
(mf/defc invite-members-modal
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :invite-members
|
::mf/register-as :invite-members
|
||||||
::mf/wrap-props false}
|
::mf/props :obj}
|
||||||
[{:keys [team origin invite-email]}]
|
[{:keys [team origin invite-email]}]
|
||||||
(let [members-map (mf/deref refs/dashboard-team-members)
|
(let [members-map (mf/deref refs/dashboard-team-members)
|
||||||
perms (:permissions team)
|
perms (:permissions team)
|
||||||
|
@ -143,8 +146,10 @@
|
||||||
(get-available-roles perms))
|
(get-available-roles perms))
|
||||||
team-id (:id team)
|
team-id (:id team)
|
||||||
|
|
||||||
initial (mf/with-memo [team-id]
|
initial (mf/with-memo [team-id invite-email]
|
||||||
{:role "editor" :team-id team-id})
|
(if invite-email
|
||||||
|
{:role "editor" :team-id team-id :emails #{invite-email}}
|
||||||
|
{:role "editor" :team-id team-id}))
|
||||||
|
|
||||||
form (fm/use-form :schema schema:invite-member-form
|
form (fm/use-form :schema schema:invite-member-form
|
||||||
:initial initial)
|
:initial initial)
|
||||||
|
@ -230,8 +235,7 @@
|
||||||
:trim true
|
:trim true
|
||||||
:valid-item-fn sm/parse-email
|
:valid-item-fn sm/parse-email
|
||||||
:caution-item-fn current-members-emails
|
:caution-item-fn current-members-emails
|
||||||
:label (tr "modals.invite-member.emails")
|
:label (tr "modals.invite-member.emails")}]]
|
||||||
:invite-email invite-email}]]
|
|
||||||
|
|
||||||
[:div {:class (stl/css :action-buttons)}
|
[:div {:class (stl/css :action-buttons)}
|
||||||
[:> fm/submit-button*
|
[:> fm/submit-button*
|
||||||
|
@ -245,7 +249,7 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(mf/defc member-info
|
(mf/defc member-info
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [member profile]}]
|
[{:keys [member profile]}]
|
||||||
(let [is-you? (= (:id profile) (:id member))]
|
(let [is-you? (= (:id profile) (:id member))]
|
||||||
[:*
|
[:*
|
||||||
|
@ -258,7 +262,7 @@
|
||||||
[:div {:class (stl/css :member-email)} (:email member)]]]))
|
[:div {:class (stl/css :member-email)} (:email member)]]]))
|
||||||
|
|
||||||
(mf/defc rol-info
|
(mf/defc rol-info
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [member team on-set-admin on-set-editor on-set-owner on-set-viewer profile]}]
|
[{:keys [member team on-set-admin on-set-editor on-set-owner on-set-viewer profile]}]
|
||||||
(let [member-is-owner (:is-owner member)
|
(let [member-is-owner (:is-owner member)
|
||||||
member-is-admin (and (:is-admin member) (not member-is-owner))
|
member-is-admin (and (:is-admin member) (not member-is-owner))
|
||||||
|
@ -309,7 +313,7 @@
|
||||||
(tr "labels.owner")])]]]))
|
(tr "labels.owner")])]]]))
|
||||||
|
|
||||||
(mf/defc member-actions
|
(mf/defc member-actions
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [member team on-delete on-leave profile]}]
|
[{:keys [member team on-delete on-leave profile]}]
|
||||||
(let [is-owner? (:is-owner member)
|
(let [is-owner? (:is-owner member)
|
||||||
owner? (dm/get-in team [:permissions :is-owner])
|
owner? (dm/get-in team [:permissions :is-owner])
|
||||||
|
@ -345,7 +349,7 @@
|
||||||
|
|
||||||
(mf/defc team-member
|
(mf/defc team-member
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/props :obj}
|
||||||
[{:keys [team member members profile]}]
|
[{:keys [team member members profile]}]
|
||||||
|
|
||||||
(let [member-id (:id member)
|
(let [member-id (:id member)
|
||||||
|
@ -479,7 +483,7 @@
|
||||||
:on-leave on-leave'}]]]))
|
:on-leave on-leave'}]]]))
|
||||||
|
|
||||||
(mf/defc team-members
|
(mf/defc team-members
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [members-map team profile]}]
|
[{:keys [members-map team profile]}]
|
||||||
(let [members (mf/with-memo [members-map]
|
(let [members (mf/with-memo [members-map]
|
||||||
(->> (vals members-map)
|
(->> (vals members-map)
|
||||||
|
@ -510,8 +514,8 @@
|
||||||
:members members-map}])]]))
|
:members members-map}])]]))
|
||||||
|
|
||||||
(mf/defc team-members-page
|
(mf/defc team-members-page
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [team profile invite-email]}]
|
[{:keys [team profile]}]
|
||||||
(let [members-map (mf/deref refs/dashboard-team-members)]
|
(let [members-map (mf/deref refs/dashboard-team-members)]
|
||||||
|
|
||||||
(mf/with-effect [team]
|
(mf/with-effect [team]
|
||||||
|
@ -525,7 +529,7 @@
|
||||||
(st/emit! (dd/fetch-team-members (:id team))))
|
(st/emit! (dd/fetch-team-members (:id team))))
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
[:& header {:section :dashboard-team-members :team team :invite-email invite-email}]
|
[:& header {:section :dashboard-team-members :team team}]
|
||||||
[:section {:class (stl/css :dashboard-container :dashboard-team-members)}
|
[:section {:class (stl/css :dashboard-container :dashboard-team-members)}
|
||||||
[:& team-members
|
[:& team-members
|
||||||
{:profile profile
|
{:profile profile
|
||||||
|
@ -536,9 +540,9 @@
|
||||||
;; INVITATIONS SECTION
|
;; INVITATIONS SECTION
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(mf/defc invitation-role-selector
|
(mf/defc invitation-role-selector*
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [can-invite? role status on-change]}]
|
[{:keys [can-invite role status on-change]}]
|
||||||
(let [show? (mf/use-state false)
|
(let [show? (mf/use-state false)
|
||||||
label (cond
|
label (cond
|
||||||
(= role :owner) (tr "labels.owner")
|
(= role :owner) (tr "labels.owner")
|
||||||
|
@ -559,7 +563,7 @@
|
||||||
(on-change role event))))]
|
(on-change role event))))]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
(if (and can-invite? (= status :pending))
|
(if (and can-invite (= status :pending))
|
||||||
[:div {:class (stl/css :rol-selector :has-priv)
|
[:div {:class (stl/css :rol-selector :has-priv)
|
||||||
:on-click on-show}
|
:on-click on-show}
|
||||||
[:span {:class (stl/css :rol-label)} label]
|
[:span {:class (stl/css :rol-label)} label]
|
||||||
|
@ -583,7 +587,7 @@
|
||||||
(tr "labels.viewer")]]]]))
|
(tr "labels.viewer")]]]]))
|
||||||
|
|
||||||
(mf/defc invitation-actions
|
(mf/defc invitation-actions
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [invitation team-id]}]
|
[{:keys [invitation team-id]}]
|
||||||
(let [show? (mf/use-state false)
|
(let [show? (mf/use-state false)
|
||||||
|
|
||||||
|
@ -678,10 +682,11 @@
|
||||||
:class (stl/css :action-dropdown-item)}
|
:class (stl/css :action-dropdown-item)}
|
||||||
(tr "labels.delete-invitation")]]]]))
|
(tr "labels.delete-invitation")]]]]))
|
||||||
|
|
||||||
(mf/defc invitation-row
|
(mf/defc invitation-row*
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/private true
|
||||||
[{:keys [invitation can-invite? team-id] :as props}]
|
::mf/props :obj}
|
||||||
|
[{:keys [invitation can-invite team-id]}]
|
||||||
|
|
||||||
(let [expired? (:expired invitation)
|
(let [expired? (:expired invitation)
|
||||||
email (:email invitation)
|
email (:email invitation)
|
||||||
|
@ -704,8 +709,8 @@
|
||||||
[:div {:class (stl/css :table-field :field-email)} email]
|
[:div {:class (stl/css :table-field :field-email)} email]
|
||||||
|
|
||||||
[:div {:class (stl/css :table-field :field-roles)}
|
[:div {:class (stl/css :table-field :field-roles)}
|
||||||
[:& invitation-role-selector
|
[:> invitation-role-selector*
|
||||||
{:can-invite? can-invite?
|
{:can-invite can-invite
|
||||||
:role role
|
:role role
|
||||||
:status status
|
:status status
|
||||||
:on-change on-change-role}]]
|
:on-change on-change-role}]]
|
||||||
|
@ -714,16 +719,16 @@
|
||||||
[:& badge-notification {:type type :content badge-content}]]
|
[:& badge-notification {:type type :content badge-content}]]
|
||||||
|
|
||||||
[:div {:class (stl/css :table-field :field-actions)}
|
[:div {:class (stl/css :table-field :field-actions)}
|
||||||
(when can-invite?
|
(when can-invite
|
||||||
[:& invitation-actions
|
[:& invitation-actions
|
||||||
{:invitation invitation
|
{:invitation invitation
|
||||||
:team-id team-id}])]]))
|
:team-id team-id}])]]))
|
||||||
|
|
||||||
(mf/defc empty-invitation-table
|
(mf/defc empty-invitation-table
|
||||||
[{:keys [can-invite?] :as props}]
|
[{:keys [can-invite] :as props}]
|
||||||
[:div {:class (stl/css :empty-invitations)}
|
[:div {:class (stl/css :empty-invitations)}
|
||||||
[:span (tr "labels.no-invitations")]
|
[:span (tr "labels.no-invitations")]
|
||||||
(when can-invite?
|
(when can-invite
|
||||||
[:> i18n/tr-html* {:content (tr "labels.no-invitations-hint")
|
[:> i18n/tr-html* {:content (tr "labels.no-invitations-hint")
|
||||||
:tag-name "span"}])])
|
:tag-name "span"}])])
|
||||||
|
|
||||||
|
@ -731,7 +736,7 @@
|
||||||
[{:keys [team invitations] :as props}]
|
[{:keys [team invitations] :as props}]
|
||||||
(let [owner? (dm/get-in team [:permissions :is-owner])
|
(let [owner? (dm/get-in team [:permissions :is-owner])
|
||||||
admin? (dm/get-in team [:permissions :is-admin])
|
admin? (dm/get-in team [:permissions :is-admin])
|
||||||
can-invite? (or owner? admin?)
|
can-invite (or owner? admin?)
|
||||||
team-id (:id team)]
|
team-id (:id team)]
|
||||||
|
|
||||||
[:div {:class (stl/css :invitations)}
|
[:div {:class (stl/css :invitations)}
|
||||||
|
@ -740,17 +745,17 @@
|
||||||
[:div {:class (stl/css :title-field-role)} (tr "labels.role")]
|
[:div {:class (stl/css :title-field-role)} (tr "labels.role")]
|
||||||
[:div {:class (stl/css :title-field-status)} (tr "labels.status")]]
|
[:div {:class (stl/css :title-field-status)} (tr "labels.status")]]
|
||||||
(if (empty? invitations)
|
(if (empty? invitations)
|
||||||
[:& empty-invitation-table {:can-invite? can-invite?}]
|
[:& empty-invitation-table {:can-invite can-invite}]
|
||||||
[:div {:class (stl/css :table-rows)}
|
[:div {:class (stl/css :table-rows)}
|
||||||
(for [invitation invitations]
|
(for [invitation invitations]
|
||||||
[:& invitation-row
|
[:> invitation-row*
|
||||||
{:key (:email invitation)
|
{:key (:email invitation)
|
||||||
:invitation invitation
|
:invitation invitation
|
||||||
:can-invite? can-invite?
|
:can-invite can-invite
|
||||||
:team-id team-id}])])]))
|
:team-id team-id}])])]))
|
||||||
|
|
||||||
(mf/defc team-invitations-page
|
(mf/defc team-invitations-page
|
||||||
[{:keys [team] :as props}]
|
[{:keys [team]}]
|
||||||
(let [invitations (mf/deref refs/dashboard-team-invitations)]
|
(let [invitations (mf/deref refs/dashboard-team-invitations)]
|
||||||
|
|
||||||
(mf/with-effect [team]
|
(mf/with-effect [team]
|
||||||
|
@ -794,7 +799,7 @@
|
||||||
(mf/defc webhook-modal
|
(mf/defc webhook-modal
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :webhook}
|
::mf/register-as :webhook}
|
||||||
[{:keys [webhook] :as props}]
|
[{:keys [webhook]}]
|
||||||
|
|
||||||
(let [initial (mf/with-memo []
|
(let [initial (mf/with-memo []
|
||||||
(or (some-> webhook (update :uri str))
|
(or (some-> webhook (update :uri str))
|
||||||
|
@ -905,7 +910,7 @@
|
||||||
(tr "modals.create-webhook.submit-label"))}]]]]]]))
|
(tr "modals.create-webhook.submit-label"))}]]]]]]))
|
||||||
|
|
||||||
(mf/defc webhooks-hero
|
(mf/defc webhooks-hero
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[]
|
[]
|
||||||
[:div {:class (stl/css :webhooks-hero-container)}
|
[:div {:class (stl/css :webhooks-hero-container)}
|
||||||
[:h2 {:class (stl/css :hero-title)}
|
[:h2 {:class (stl/css :hero-title)}
|
||||||
|
@ -939,18 +944,9 @@
|
||||||
:class (stl/css :menu-disabled)}
|
:class (stl/css :menu-disabled)}
|
||||||
[:> icon* {:id "menu"}]])))
|
[:> icon* {:id "menu"}]])))
|
||||||
|
|
||||||
(mf/defc last-delivery-icon
|
|
||||||
{::mf/wrap-props false}
|
|
||||||
[{:keys [success? text]}]
|
|
||||||
[:div {:class (stl/css :last-delivery-icon)
|
|
||||||
:title text}
|
|
||||||
(if success?
|
|
||||||
success-icon
|
|
||||||
warning-icon)])
|
|
||||||
|
|
||||||
(mf/defc webhook-item
|
(mf/defc webhook-item
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [webhook permissions] :as props}]
|
[{:keys [webhook permissions]}]
|
||||||
(let [error-code (:error-code webhook)
|
(let [error-code (:error-code webhook)
|
||||||
id (:id webhook)
|
id (:id webhook)
|
||||||
creator-id (:profile-id webhook)
|
creator-id (:profile-id webhook)
|
||||||
|
@ -1014,14 +1010,14 @@
|
||||||
:can-edit can-edit}]]]))
|
:can-edit can-edit}]]]))
|
||||||
|
|
||||||
(mf/defc webhooks-list
|
(mf/defc webhooks-list
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [webhooks permissions]}]
|
[{:keys [webhooks permissions]}]
|
||||||
[:div {:class (stl/css :table-rows :webhook-table)}
|
[:div {:class (stl/css :table-rows :webhook-table)}
|
||||||
(for [webhook webhooks]
|
(for [webhook webhooks]
|
||||||
[:& webhook-item {:webhook webhook :key (:id webhook) :permissions permissions}])])
|
[:& webhook-item {:webhook webhook :key (:id webhook) :permissions permissions}])])
|
||||||
|
|
||||||
(mf/defc team-webhooks-page
|
(mf/defc team-webhooks-page
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [team]}]
|
[{:keys [team]}]
|
||||||
(let [webhooks (mf/deref refs/dashboard-team-webhooks)]
|
(let [webhooks (mf/deref refs/dashboard-team-webhooks)]
|
||||||
|
|
||||||
|
@ -1051,7 +1047,7 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(mf/defc team-settings-page
|
(mf/defc team-settings-page
|
||||||
{::mf/wrap-props false}
|
{::mf/props :obj}
|
||||||
[{:keys [team]}]
|
[{:keys [team]}]
|
||||||
(let [finput (mf/use-ref)
|
(let [finput (mf/use-ref)
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,8 @@
|
||||||
|
|
||||||
(defn- create-form-mutator
|
(defn- create-form-mutator
|
||||||
[internal-state rerender-fn wrap-update-fn initial opts]
|
[internal-state rerender-fn wrap-update-fn initial opts]
|
||||||
|
(mf/set-ref-val! internal-state initial)
|
||||||
|
|
||||||
(reify
|
(reify
|
||||||
IDeref
|
IDeref
|
||||||
(-deref [_]
|
(-deref [_]
|
||||||
|
@ -128,6 +130,12 @@
|
||||||
[& {:keys [initial] :as opts}]
|
[& {:keys [initial] :as opts}]
|
||||||
(let [rerender-fn (use-rerender-fn)
|
(let [rerender-fn (use-rerender-fn)
|
||||||
|
|
||||||
|
initial
|
||||||
|
(mf/with-memo [initial]
|
||||||
|
{:data (if (fn? initial) (initial) initial)
|
||||||
|
:errors {}
|
||||||
|
:touched {}})
|
||||||
|
|
||||||
internal-state
|
internal-state
|
||||||
(mf/use-ref nil)
|
(mf/use-ref nil)
|
||||||
|
|
||||||
|
@ -136,11 +144,8 @@
|
||||||
(create-form-mutator internal-state rerender-fn wrap-update-schema-fn initial opts))]
|
(create-form-mutator internal-state rerender-fn wrap-update-schema-fn initial opts))]
|
||||||
|
|
||||||
;; Initialize internal state once
|
;; Initialize internal state once
|
||||||
(mf/with-effect []
|
(mf/with-layout-effect []
|
||||||
(mf/set-ref-val! internal-state
|
(mf/set-ref-val! internal-state initial))
|
||||||
{:data {}
|
|
||||||
:errors {}
|
|
||||||
:touched {}}))
|
|
||||||
|
|
||||||
(mf/with-effect [initial]
|
(mf/with-effect [initial]
|
||||||
(if (fn? initial)
|
(if (fn? initial)
|
||||||
|
|
Loading…
Reference in a new issue