diff --git a/webapp/src/clj/lipas/backend/ptv/core.clj b/webapp/src/clj/lipas/backend/ptv/core.clj index a963cb302..ba1703a5e 100644 --- a/webapp/src/clj/lipas/backend/ptv/core.clj +++ b/webapp/src/clj/lipas/backend/ptv/core.clj @@ -51,7 +51,7 @@ (defn generate-ptv-service-descriptions [search - {:keys [_id sub-category-id city-codes overview]}] + {:keys [sub-category-id city-codes overview]}] (let [doc (or overview (let [type-codes (->> (types/by-sub-category sub-category-id) (map :type-code)) @@ -107,7 +107,7 @@ :service-channel-ids]) (defn upsert-ptv-service-location!* - [tx ptv-component search user {:keys [org-id site ptv archive?] :as _m}] + [ptv-component {:keys [org-id site ptv archive?] :as _m}] (let [id (-> ptv :service-channel-ids first) ;; merge or just replace? site (update site :ptv merge ptv) @@ -122,13 +122,18 @@ ;; Store the new PTV info to Lipas DB new-ptv-data (-> ptv (select-keys persisted-ptv-keys) - (assoc :last-sync now + (assoc :org-id (or (:org-id ptv) + org-id) + :last-sync now ;; Store the current type-code into ptv data, so this can be ;; used to comapre if the services need to recalculated on site data update. :previous-type-code (:type-code (:type site)) :source-id (:sourceId ptv-resp) ;; Store the PTV status so we can ignore Lipas archived places that we already archived in PTV. :publishing-status (:publishingStatus ptv-resp) + ;; NOTE: The ptv map might not have this value in some cases...? + ;; but the value merged with data from site should have it always? + :service-ids (:service-ids (:ptv site)) ;; Take the created ID from ptv response and store to Lipas DB right away. ;; TODO: Is there a case where this could be multiple ids? :service-channel-ids [(:id ptv-resp)]) @@ -149,7 +154,7 @@ (let [site (db/get-sports-site db lipas-id) _ (assert (some? site) (str "Sports site " lipas-id " not found in DB")) - [ptv-resp new-ptv-data] (upsert-ptv-service-location!* tx ptv-component search user + [ptv-resp new-ptv-data] (upsert-ptv-service-location!* ptv-component {:org-id org-id :site site :ptv ptv @@ -176,9 +181,10 @@ (:serviceChannelNames ptv-resp))}}))) (comment + (require '[integrant.repl.state :as state]) - (let [ptv-component (:lipas/ptv integrant.repl.state/system) - org-id ptv-data/liminka-org-id-test + (let [ptv-component (:lipas/ptv state/system) + org-id "7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5" services (:itemList (ptv/get-org-services ptv-component org-id))] (->> services (utils/index-by :sourceId) @@ -240,7 +246,7 @@ (vec x))))) ptv) - [_ptv-resp new-ptv-data] (upsert-ptv-service-location!* tx ptv-component search user + [_ptv-resp new-ptv-data] (upsert-ptv-service-location!* ptv-component {:org-id org-id :ptv ptv :site sports-site diff --git a/webapp/src/clj/lipas/backend/ptv/handler.clj b/webapp/src/clj/lipas/backend/ptv/handler.clj index 050723b2a..5d4192c10 100644 --- a/webapp/src/clj/lipas/backend/ptv/handler.clj +++ b/webapp/src/clj/lipas/backend/ptv/handler.clj @@ -6,9 +6,9 @@ (defn localized-string-schema [string-props] [:map {:closed true} - [:fi [:string string-props]] - [:se [:string string-props]] - [:en [:string string-props]]]) + [:fi {:optional true} [:string string-props]] + [:se {:optional true} [:string string-props]] + [:en {:optional true} [:string string-props]]]) (def integration-enum [:enum "lipas-managed" "manual"]) @@ -16,7 +16,7 @@ (def ptv-meta [:map {:closed true} - ;; [:org-id :string] + [:org-id :string] [:sync-enabled :boolean] ;; These options aren't used now: @@ -29,7 +29,7 @@ integration-enum] [:service-channel-ids [:vector :string]] - ;; [:service-ids [:vector :string]] + [:service-ids [:vector :string]] ;; [:languages [:vector :string]] [:summary (localized-string-schema {:max 150})] @@ -53,7 +53,7 @@ {:require-privilege :ptv/manage :parameters {:body [:map [:city-codes [:vector :int]] - [ :type-codes {:optional true} [:vector :int]] + [:type-codes {:optional true} [:vector :int]] [:owners [:vector :string]]]} :handler (fn [req] @@ -101,11 +101,7 @@ {:post {:require-privilege :ptv/manage :parameters {:body [:map - [:org-id :string] [:city-codes [:vector :int]] - [:owners [:vector :string]] - [:supported-languages [:vector [:enum "fi" "se" "en"]]] - [:sourceId :string] [:sub-category-id :int] [:overview {:optional true :description "Use this to replace the AI input with non-saved site information"} @@ -182,9 +178,9 @@ {:require-privilege :ptv/manage :parameters {:body create-ptv-service-location} :handler - (fn [{:keys [body-params identity]}] + (fn [req] {:status 200 - :body (ptv-core/upsert-ptv-service-location! db ptv search identity body-params)})}}] + :body (ptv-core/upsert-ptv-service-location! db ptv search (:identity req) (-> req :parameters :body))})}}] ["/actions/save-ptv-meta" {:post @@ -192,6 +188,6 @@ :coercion reitit.coercion.spec/coercion :parameters {:body :lipas.sports-site/ptv} :handler - (fn [{:keys [identity] :as req}] + (fn [req] {:status 200 - :body (ptv-core/save-ptv-integration-definitions db search identity (-> req :parameters :body))})}}]]) + :body (ptv-core/save-ptv-integration-definitions db search (:identity req) (-> req :parameters :body))})}}]]) diff --git a/webapp/src/clj/lipas/backend/ptv/integration.clj b/webapp/src/clj/lipas/backend/ptv/integration.clj index ea84f332f..ec8704cc3 100644 --- a/webapp/src/clj/lipas/backend/ptv/integration.clj +++ b/webapp/src/clj/lipas/backend/ptv/integration.clj @@ -55,6 +55,9 @@ In test-env token seems to be valid for 24h." [{:keys [token-url username password org-id]}] (let [token-key (if (test-env? token-url) :ptvToken :serviceToken) ; wtf + ;; Prod needs a different type of ID for apiUserOrganisation value + user-org-id (or (:prod-org-id (get ptv-data/org-id->params org-id)) + org-id) req {:url token-url :method :post :as :json @@ -62,8 +65,8 @@ :content-type :json :form-params (merge {:username username :password password} - (when org-id - {:apiUserOrganisation org-id}))}] + (when user-org-id + {:apiUserOrganisation user-org-id}))}] (-> (client/request req) :body token-key))) @@ -110,11 +113,13 @@ ;; NOTE: Looks like tokens from yesterday aren't valid the next day even if they haven't "expired" yet? (if (and (not retried?) (= 401 (:status d)) + ;; Just retry once for every 401 + #_ (= "Bearer error=\"invalid_token\", error_description=\"The access token is not valid.\"" (get (:headers d) "WWW-Authenticate"))) (do (log/infof "Invalid token, trying to get a new token and retry") - (swap! (:tokens ptv) dissoc (:auth-org-id req)) + (swap! (:tokens ptv) dissoc auth-org-id) (http ptv auth-org-id req true)) (throw (ex-info (format "HTTP Error: %s %s" (:status d) (:body d)) {:resp d @@ -190,7 +195,6 @@ [ptv service-location] (let [org-id (-> service-location :organizationId) params {:url (make-url ptv "/v11/ServiceChannel/ServiceLocation") - :auth-org-id org-id :method :post :form-params service-location}] (log/info "Create PTV service location" service-location) @@ -244,18 +248,20 @@ (def ptv* (:lipas/ptv state/system)) - (get-org-services ptv* ptv-data/liminka-org-id-test) + (def org-id* "7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5") + + (get-org-services ptv* org-id*) ;; Delete all org services - (doseq [x (:itemList (get-org-services ptv* ptv-data/liminka-org-id-test))] + (doseq [x (:itemList (get-org-services ptv* org-id*))] (update-service ptv* (:sourceId x) - {:mainResponsibleOrganization ptv-data/liminka-org-id-test + {:mainResponsibleOrganization org-id* :publishingStatus "Deleted"})) (get-service ptv* - ptv-data/liminka-org-id-test - (-> (get-org-services {} ptv-data/liminka-org-id-test) + org-id* + (-> (get-org-services {} org-id*) :itemList first :id)) @@ -279,14 +285,17 @@ :let [site (core/get-sports-site (user/db) (:lipas-id search-site))]] (core/index! (user/search) site :sync)) - (get-org-service-channels ptv* ptv-data/liminka-org-id-test) + (get-org-service-channels ptv* org-id*) + + (http ptv* org-id* {:url (make-url ptv* "/v11/ServiceChannel/b4abd13e-0d36-4ff9-a6c9-94f2f5aee036") + :method :get}) ;; Delete all org service locations - (doseq [x (:itemList (get-org-service-channels ptv* ptv-data/liminka-org-id-test))] - (update-service-location ptv* (:id x) {:organizationId ptv-data/liminka-org-id-test + (doseq [x (:itemList (get-org-service-channels ptv* org-id*))] + (update-service-location ptv* (:id x) {:organizationId org-id* :publishingStatus "Deleted"})) (update-service-location ptv* "fc768bb4-268c-4054-9b88-9ecc9a943452" - {:org-id ptv-data/liminka-org-id-test + {:org-id org-id* :publishingStatus "Deleted"})) diff --git a/webapp/src/cljc/lipas/data/ptv.cljc b/webapp/src/cljc/lipas/data/ptv.cljc index 65d5af9f7..632a9a9df 100644 --- a/webapp/src/cljc/lipas/data/ptv.cljc +++ b/webapp/src/cljc/lipas/data/ptv.cljc @@ -17,30 +17,36 @@ ;; org 10 #_(def uta-org-id-test "52e0f6dc-ec1f-48d5-a0a2-7a4d8b657d53") -;; Testiorganisaatio 6 (Kunta) -(def uta-org-id-test "3d1759a2-e47a-4947-9a31-cab1c1e2512b") - -;; org 9 -(def liminka-org-id-test "7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5") - ;; org 8 #_(def uta-org-id-test "92374b0f-7d3c-4017-858e-666ee3ca2761") #_(def uta-org-id-prod "7b83257d-06ad-4e3b-985d-16a5c9d3fced") ;; TODO: Tulossa 5 kuntaa, muut: ;; (Lumijoki. Pyhäjärvi, Ii, Liminka ja Oulu sekä tietenkin bonuksena Utajärvi). +;; TODO: Kuinka valita näytetäänkö test vai prod organisaatiot? (def organizations [{:name "Utajärven kunta (test)" - :props {:org-id uta-org-id-test + :props {;; Testiorganisaatio 6 (Kunta) + :org-id "3d1759a2-e47a-4947-9a31-cab1c1e2512b" + :city-codes [889] + :owners ["city" "city-main-owner"] + :supported-languages ["fi"]}} + {:name "Utajärven kunta (prod)" + :props {:org-id "7b83257d-06ad-4e3b-985d-16a5c9d3fced" + ;; Production authentication apiUserOrganisation field uses different + ;; "persistent org-id" value. This option is used to map the "version org-id" + ;; that is used elsewhere to this version for the auth. + :prod-org-id "9f095753-3ca9-4d89-b7e4-3cdf83bb44b2" :city-codes [889] :owners ["city" "city-main-owner"] - :supported-languages ["fi" "se" "en"]}} + :supported-languages ["fi"]}} {:name "Limingan kunta (test)" - :props {:org-id liminka-org-id-test + :props {;; org 9 + :org-id "7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5" :city-codes [425] :owners ["city" "city-main-owner"] - :supported-languages ["fi" "se" "en"]}} ]) + :supported-languages ["fi" #_#_ "se" "en"]}}]) ;; For adding default params to some requests from the FE ;; NOTE: This should eventually be replaced with Lipas organizations. @@ -70,6 +76,16 @@ (def default-langs ["fi"]) +;; NOTE: Right now the UI mostly just uses this always. +;; The languages value is also stored to sports-site :ptv on +;; sync, but that value isn't used now? +;; So it is possible to enable new languages by modying the org config. +;; Summary/description texts are always generated for all languages, +;; but additional languages aren't shown on the FE or sent to PTV. +(defn org-id->languages [org-id] + (or (:supported-languages (get org-id->params org-id)) + default-langs)) + (defn ->service-source-id [org-id sub-category-id] (str "lipas-" org-id "-" sub-category-id)) @@ -181,7 +197,7 @@ })) (defn ->ptv-service-location - [_org + [org-id coord-transform-fn now {:keys [status ptv lipas-id location search-meta] :as sports-site}] @@ -198,7 +214,7 @@ ; (println "Languages resolved" languages) ; (prn location) - {:organizationId (:org-id ptv) + {:organizationId (or (:org-id ptv) org-id) ;; Keep using existing sourceId for sites that were already initialized in PTV, ;; generate a new unique ID (with timestamp) for new sites. :sourceId (or (:source-id ptv) @@ -363,7 +379,12 @@ ) (defn parse-service-source-id [source-id] - ()) + (-> (re-find #"lipas-.*-(\d*)" source-id) + second + parse-long)) + +(comment + (parse-service-source-id "lipas-7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5-6100")) (defn index-services [services] ) @@ -420,6 +441,7 @@ (defn sports-site->ptv-input [{:keys [types org-id org-defaults org-langs]} service-channels services site] (let [service-id (-> site :ptv :service-ids first) service-channel-id (-> site :ptv :service-channel-ids first) + summary (-> site :ptv :summary) description (-> site :ptv :description) diff --git a/webapp/src/cljs/lipas/ui/ptv/controls.cljs b/webapp/src/cljs/lipas/ui/ptv/controls.cljs index 38dd8dcf9..688be2b65 100644 --- a/webapp/src/cljs/lipas/ui/ptv/controls.cljs +++ b/webapp/src/cljs/lipas/ui/ptv/controls.cljs @@ -33,10 +33,13 @@ :on-change (fn [_e v] (on-change (:value v)))}))) -(defui lang-selector [{:keys [value on-change]}] +(defui lang-selector [{:keys [value on-change enabled-languages]}] ($ Tabs {:value value :on-change (fn [_e v] (on-change (keyword v)))} - ($ Tab {:value "fi" :label "FI"}) - ($ Tab {:value "se" :label "SE"}) - ($ Tab {:value "en" :label "EN"}))) + (when (or (nil? enabled-languages) (contains? enabled-languages "fi")) + ($ Tab {:value "fi" :label "FI"})) + (when (or (nil? enabled-languages) (contains? enabled-languages "se")) + ($ Tab {:value "se" :label "SE"})) + (when (or (nil? enabled-languages) (contains? enabled-languages "en")) + ($ Tab {:value "en" :label "EN"})))) diff --git a/webapp/src/cljs/lipas/ui/ptv/events.cljs b/webapp/src/cljs/lipas/ui/ptv/events.cljs index b4a7edede..263a530e8 100644 --- a/webapp/src/cljs/lipas/ui/ptv/events.cljs +++ b/webapp/src/cljs/lipas/ui/ptv/events.cljs @@ -33,7 +33,8 @@ {:method :post :headers {:Authorization (str "Token " token)} :uri (str (:backend-url db) "/actions/get-ptv-integration-candidates") - :params (get ptv-data/org-id->params (:id org)) + :params (-> (get ptv-data/org-id->params (:id org)) + (select-keys [:city-codes :type-codes :owners])) :format (ajax/transit-request-format) :response-format (ajax/transit-response-format) :on-success [::fetch-integration-candidates-success (:id org)] @@ -426,11 +427,9 @@ :headers {:Authorization (str "Token " token)} :uri (str (:backend-url db) "/actions/generate-ptv-service-descriptions") - :params (merge - (ptv-data/org-id->params org-id) - {:sourceId id - :sub-category-id (parse-long (last (str/split id #"-"))) - :overview overview}) + :params {:city-codes (:city-codes (ptv-data/org-id->params org-id)) + :sub-category-id (parse-long (last (str/split id #"-"))) + :overview overview} :format (ajax/transit-request-format) :response-format (ajax/transit-response-format) :on-success [::generate-service-descriptions-success org-id id success-fx] @@ -512,9 +511,8 @@ {:method :post :headers {:Authorization (str "Token " token)} :uri (str (:backend-url db) "/actions/save-ptv-service") - ;; FIXME: org-id->params adds some extra keys that aren't used? - ;; supported-languages (languages is used instead) - :params (merge data (ptv-data/org-id->params org-id)) + :params (merge (select-keys (ptv-data/org-id->params org-id) [:org-id :city-codes]) + data) :format (ajax/transit-request-format) :response-format (ajax/transit-response-format) :on-success [::create-ptv-service-success org-id id success-fx] @@ -617,14 +615,21 @@ ;; Add default org-id for service-ids linking sports-site (update sports-site :ptv #(merge {:org-id org-id} %)) - service-ids (ptv-data/sports-site->service-ids types source-id->service sports-site) + service-ids (vec (ptv-data/sports-site->service-ids types source-id->service sports-site)) ;; Add other defaults and merge with summary/description from the UI - ptv-data (merge (:default-settings (:ptv db)) + ptv-data (merge (select-keys (:default-settings (:ptv db)) + [:sync-enabled]) {:service-ids service-ids :service-channel-ids []} - ;; {:org-id org-id} - (:ptv sports-site))] + (select-keys (:ptv sports-site) + [:org-id + :sync-enabled + :service-channel-ids + ;; Use when editing? + ;; :service-ids + :summary + :description]))] {:db (assoc-in db [:ptv :loading-from-lipas :service-locations] true) :fx [[:http-xhrio {:method :post diff --git a/webapp/src/cljs/lipas/ui/ptv/site_view.cljs b/webapp/src/cljs/lipas/ui/ptv/site_view.cljs index a08d527d8..b9370071a 100644 --- a/webapp/src/cljs/lipas/ui/ptv/site_view.cljs +++ b/webapp/src/cljs/lipas/ui/ptv/site_view.cljs @@ -29,7 +29,7 @@ [selected-tab set-selected-tab] (uix/use-state :fi) - org-languages (use-subscribe [::subs/org-languages org-id]) + org-languages (ptv-data/org-id->languages org-id) service-candidate-descriptions (use-subscribe [::subs/service-candidate-descriptions org-id]) {:keys [summary description]} (get service-candidate-descriptions source-id) @@ -68,7 +68,8 @@ ($ controls/lang-selector {:value selected-tab - :on-change set-selected-tab}) + :on-change set-selected-tab + :enabled-languages (set org-languages)}) ;; Summary (r/as-element @@ -115,7 +116,6 @@ editing* (boolean (use-subscribe [:lipas.ui.sports-sites.subs/editing? lipas-id])) editing? (and can-edit? editing*) - read-only? (not editing?) sports-site (use-subscribe [:lipas.ui.sports-sites.subs/latest-rev lipas-id]) ;; NOTE: Edit-data and sports-site schema can be a bit different. @@ -127,6 +127,7 @@ ;; _ (js/console.log edit-data sports-site) {:keys [org-id sync-enabled last-sync publishing-status]} (:ptv site) + org-languages (ptv-data/org-id->languages org-id) ;; _ (js/console.log org-id) @@ -142,13 +143,17 @@ ready? (ptv-data/ptv-ready? site) candidate-now? (ptv-data/ptv-candidate? site) + read-only? (or (not editing?) + (not candidate-now?)) + types (use-subscribe [:lipas.ui.sports-sites.subs/all-types]) loading-ptv? (use-subscribe [::subs/loading-from-ptv?]) + services (use-subscribe [::subs/services-by-id org-id]) missing-services-input [{:service-ids #{} :sub-category-id (-> site :type :type-code types :sub-category) :sub-category (-> site :search-meta :type :sub-category :name :fi)}] - missing-services (when (and org-id (not loading-ptv?)) + missing-services (when (and org-id candidate-now? (not loading-ptv?)) (ptv-data/resolve-missing-services org-id services missing-services-input)) source-id->service (utils/index-by :sourceId (vals services)) @@ -168,24 +173,38 @@ ($ Stack {:direction "column" - :sx #js {:gap 2}} + :sx #js {:gap 2 + :position "relative"}} - ;; TODO: Spinneri? (when loading-ptv? - ($ Alert {:severity "info"} - "Ladataan PTV tietoja...")) - - ; ($ FormControl - ; ($ FormLabel - ; "Lipas tila") - ; ($ Typography - ; status)) + ($ Stack + {:severity "info" + :sx #js {:position "absolute" + :background "rgba(255, 255, 255, 0.7)" + :zIndex 2000 + :top "0" + :left "0" + :width "100%" + :height "100%"}} + ($ Stack + {:direction "column" + :alignItems "center" + :sx #js {:position "absolute" + :top "50%" + :left "50%" + :transform "translateX(-50%) translateY(-50%)" + :gap 2}} + ($ CircularProgress) + "Ladataan PTV tietoja..."))) - (when (not (:org-id (:ptv site))) + (when (and candidate-now? (not (:org-id (:ptv site)))) ($ :<> ($ Alert {:severity "warning"} "Valitse organisaatio:"))) + (when (not candidate-now?) + ($ Alert {:severity "warning"} "Paikkaa ei viedä PTV (Lipas tila, tyyppi, omistaja)")) + (let [options (uix/use-memo (fn [] (->> ptv-data/orgs (map (fn [{:keys [name id]}] @@ -221,11 +240,11 @@ (and candidate-now? ready?) ($ Alert {:severity "info"} "Paikkaa ei viety PTV, mutta palvelu paikka luodaan tallennuksessa") - (not ready?) + (and candidate-now? (not ready?)) ($ Alert {:severity "info"} "PTV tiedot ovat vielä puutteelliset, täytä tiedot niin paikka viedään PTV tallennuksen yhteydessä") :else - ($ Alert {:severity "warning"} "Paikka näyttää siltä ettei sitä pidä viedä PTV") + "-" ; ($ Typography ; publishing-status) @@ -285,7 +304,9 @@ ($ controls/lang-selector {:value selected-tab - :on-change set-selected-tab}) + :on-change set-selected-tab + :enabled-languages (set (or (:languages (:ptv site)) + org-languages))}) ;; Summary (r/as-element diff --git a/webapp/src/cljs/lipas/ui/ptv/subs.cljs b/webapp/src/cljs/lipas/ui/ptv/subs.cljs index eb7233497..2f5b6b063 100644 --- a/webapp/src/cljs/lipas/ui/ptv/subs.cljs +++ b/webapp/src/cljs/lipas/ui/ptv/subs.cljs @@ -61,24 +61,6 @@ (fn [[ptv org-defaults] _] (merge (:default-settings ptv) org-defaults))) -(def lang - {"fi" "fi" - "sv" "se" - "en" "en"}) - -(rf/reg-sub ::org-languages - :<- [::ptv] - (fn [ptv [_ org-id]] - ;; There are (undocumented) business rules regarding in which lang - ;; data can be entered. One of the rules seems to be that the org - ;; must be described with all the desired languages before other - ;; data can be entered. AFAIK there's no direct way to get the org - ;; 'supported languages' so we infer them from org name - ;; translations. wtf - (->> (get-in ptv [:org org-id :data :org org-id :organizationNames]) - (keep #(get lang (:language %))) - vec))) - (rf/reg-sub ::selected-org-data :<- [::ptv] (fn [ptv [_ org-id]] @@ -133,6 +115,13 @@ :service-name service-name :service-modified (:modified service) :service-channels (->> service :serviceChannels (map :serviceChannel)) + :city-codes (->> service + :areas + (mapcat (fn [{:keys [type municipalities]}] + (when (= "Municipality" type) + municipalities))) + (map (comp parse-long :code)) + vec) :ontology-terms (->> service :ontologyTerms (map (fn [m] @@ -168,16 +157,15 @@ (rf/reg-sub ::service-candidates (fn [[_ org-id]] [(rf/subscribe [::missing-services org-id]) - (rf/subscribe [::service-candidate-descriptions org-id]) - (rf/subscribe [::org-languages org-id])]) - (fn [[missing-services descriptions org-langs] _] + (rf/subscribe [::service-candidate-descriptions org-id])]) + (fn [[missing-services descriptions] [_ org-id]] (->> missing-services (map (fn [{:keys [source-id] :as m}] (let [description (get-in descriptions [source-id :description]) - summary (get-in descriptions [source-id :summary])] + summary (get-in descriptions [source-id :summary]) + languages (ptv-data/org-id->languages org-id)] (-> m - (assoc :languages (or (get-in descriptions [source-id :languages]) - org-langs)) + (assoc :languages languages) (assoc :description description) (assoc :summary summary) (assoc :valid (boolean (and @@ -210,11 +198,11 @@ (rf/subscribe [::services-by-id org-id]) (rf/subscribe [::service-channels-by-id org-id]) (rf/subscribe [::default-settings org-id]) - (rf/subscribe [:lipas.ui.sports-sites.subs/all-types]) - (rf/subscribe [::org-languages org-id])]) - (fn [[ptv services service-channels org-defaults types org-langs] [_ org-id]] + (rf/subscribe [:lipas.ui.sports-sites.subs/all-types])]) + (fn [[ptv services service-channels org-defaults types] [_ org-id]] (let [lipas-id->site (get-in ptv [:org org-id :data :sports-sites])] - (for [site (vals lipas-id->site)] + (for [site (vals lipas-id->site) + :let [org-langs (ptv-data/org-id->languages org-id)]] (ptv-data/sports-site->ptv-input {:org-id org-id :types types :org-defaults org-defaults diff --git a/webapp/src/cljs/lipas/ui/ptv/views.cljs b/webapp/src/cljs/lipas/ui/ptv/views.cljs index 0c559cebb..e46bc9974 100644 --- a/webapp/src/cljs/lipas/ui/ptv/views.cljs +++ b/webapp/src/cljs/lipas/ui/ptv/views.cljs @@ -6,6 +6,7 @@ ["@mui/material/AccordionDetails$default" :as AccordionDetails] ["@mui/material/AccordionSummary$default" :as AccordionSummary] ["@mui/material/Avatar$default" :as Avatar] + ["@mui/material/Button$default" :as Button] ["@mui/material/Icon$default" :as Icon] ["@mui/material/Paper$default" :as Paper] ["@mui/material/Stack$default" :as Stack] @@ -77,7 +78,8 @@ (defn form [{:keys [org-id tr site]}] - (let [services @(rf/subscribe [::subs/services org-id])] + (let [services @(rf/subscribe [::subs/services org-id]) + org-languages (ptv-data/org-id->languages org-id)] [mui/grid {:container true :spacing 2 @@ -124,12 +126,10 @@ (when loading? [mui/circular-progress]) - [mui/tabs - {:value @selected-tab - :on-change #(reset! selected-tab (keyword %2))} - [mui/tab {:value "fi" :label "FI"}] - [mui/tab {:value "se" :label "SE"}] - [mui/tab {:value "en" :label "EN"}]] + ($ controls/lang-selector + {:value @selected-tab + :on-change #(reset! selected-tab %) + :enabled-languages (set org-languages)}) ;; Summary [lui/text-field @@ -687,17 +687,22 @@ :service-channel-ids service-channel-ids}))]]]])) (defn service-panel - [{:keys [service]}] + [{:keys [org-id service descriptions]}] (r/with-let [lang (r/atom "fi")] - (let [tr (<== [:lipas.ui.subs/translator])] + (let [tr (<== [:lipas.ui.subs/translator]) + source-id (:source-id service) + loading? false + org-languages (ptv-data/org-id->languages org-id) + ;; Turn the PTV Service data structure back to Lipas API call for save! + data {:org-id org-id + :source-id source-id + :city-codes (:city-codes service) + :sub-category-id (ptv-data/parse-service-source-id (:source-id service)) + :languages org-languages + :summary (or (:summary descriptions) (:summary service)) + :description (or (:description descriptions) (:description service))}] [lui/expansion-panel {:label (:label service)} - [mui/stack {:spacing 2} - [lang-selector - {:value @lang - :opts (:languages service) - :on-change #(reset! lang %2)}] - [mui/stack {:direction "row" :spacing 2} [mui/stack {:spacing 2 :flex 1} @@ -722,25 +727,35 @@ ^{:key label} [mui/chip {:label label :variant "outlined"}])))] + [lang-selector + {:value @lang + :opts (:languages service) + :on-change #(reset! lang %2)}] + ;; Summary [mui/typography (tr :ptv/summary)] - [mui/typography {:variant "body2"} (get-in service [:summary @lang])] - #_[lui/text-field - {:disabled true - :on-change #() - :multiline true - :label (tr :ptv/summary) - :value (get-in service [:summary @lang])}] + [lui/text-field + {:disabled loading? + :on-change #(==> [::events/set-service-candidate-summary source-id @lang %]) + :multiline true + :label (tr :ptv/summary) + :value (get-in data [:summary @lang])}] ;; Descriptions [mui/typography (tr :ptv/description)] - [mui/typography {:variant "body2"} (get-in service [:description @lang])] - #_[lui/text-field - {:disabled true - :on-change #() - :multiline true - :label (tr :ptv/description) - :value (get-in service [:description @lang])}]] + [lui/text-field + {:disabled loading? + :on-change #(==> [::events/set-service-candidate-description source-id @lang %]) + :multiline true + :label (tr :ptv/description) + :value (get-in data [:description @lang])}] + + ($ Button + {:variant "contained" + :disabled loading? + :on-click (fn [_e] + (rf/dispatch [::events/create-ptv-service org-id source-id data [] []]))} + "Tallenna")] [mui/stack {:spacing 2 :flex 1} @@ -758,7 +773,8 @@ (let [tr (<== [:lipas.ui.subs/translator]) services-filter (<== [::subs/services-filter]) org-id (<== [::subs/selected-org-id]) - services (<== [::subs/services-filtered org-id])] + services (<== [::subs/services-filtered org-id]) + descriptions (<== [::subs/service-candidate-descriptions org-id])] [mui/paper ;; Filter checkbox @@ -771,7 +787,10 @@ (doall (for [service services] ^{:key (:service-id service)} - [service-panel {:service service}]))])) + [service-panel + {:org-id org-id + :service service + :descriptions (get descriptions (:source-id service))}]))])) (defn wizard [] diff --git a/webapp/src/cljs/lipas/ui/sports_sites/events.cljs b/webapp/src/cljs/lipas/ui/sports_sites/events.cljs index 8c0c66801..7b8211369 100644 --- a/webapp/src/cljs/lipas/ui/sports_sites/events.cljs +++ b/webapp/src/cljs/lipas/ui/sports_sites/events.cljs @@ -1,5 +1,6 @@ (ns lipas.ui.sports-sites.events (:require [ajax.core :as ajax] + [lipas.data.ptv :as ptv-data] [lipas.roles :as roles] [lipas.ui.interceptors :as interceptors] [lipas.ui.utils :as utils] @@ -29,7 +30,11 @@ ;; NOTE: Does add extra slowness to any ::edit-field calls... (cond-> (:ptv sports-site) - (update :ptv #(merge (:default-settings (:ptv db)) %))))) + (update :ptv (fn [v] + (let [org-langs (ptv-data/org-id->languages (:org-id v))] + (merge (:default-settings (:ptv db)) + {:languages org-langs} + v))))))) (rf/reg-event-db ::calc-derived-fields (fn [db [_ lipas-id sports-site]] diff --git a/webapp/test/clj/lipas/backend/ptv_test.clj b/webapp/test/clj/lipas/backend/ptv_test.clj index 75374485d..b7c38b2c3 100644 --- a/webapp/test/clj/lipas/backend/ptv_test.clj +++ b/webapp/test/clj/lipas/backend/ptv_test.clj @@ -38,7 +38,8 @@ site body ;; TODO: Use another id for tests run? - org-id ptv-data/liminka-org-id-test + ;; Liminka, org 9 + org-id "7fdd7f84-e52a-4c17-a59a-d7c2a3095ed5" org-langs ["fi" "se" "en"] ;; re-frame app-db defaults types types/all