Compare commits

...

384 Commits

Author SHA1 Message Date
Frappe PR Bot
cf849f7dff chore(release): Bumped to Version 1.53.1 2025-09-25 16:33:11 +00:00
Shariq Ansari
3e9fdb8d20
Merge pull request #1287 from frappe/main-hotfix 2025-09-25 22:02:44 +05:30
Shariq Ansari
260755fd2e
Merge pull request #1286 from frappe/mergify/bp/main-hotfix/pr-1279 2025-09-25 21:57:28 +05:30
Shariq Ansari
85df56b464
Merge pull request #1285 from frappe/mergify/bp/main-hotfix/pr-1284 2025-09-25 21:53:53 +05:30
Shariq Ansari
a9e956b5fc chore: Norwegian Bokmal translations
(cherry picked from commit 9e92282e25cd1d3e5c33b87b02ad6dfdc09158cc)
2025-09-25 16:23:42 +00:00
Shariq Ansari
905eb63c5f chore: Serbian (Latin) translations
(cherry picked from commit 0138716e070b8098fd37c3ee67496c7a0d1ff473)
2025-09-25 16:23:42 +00:00
Shariq Ansari
3eee437014 chore: Serbian (Cyrillic) translations
(cherry picked from commit 589c95e263bf70fda044ef841a623ccda510c744)
2025-09-25 16:23:42 +00:00
Shariq Ansari
4498de2041 chore: Norwegian Bokmal translations
(cherry picked from commit a4e2663b2418c935c8279fab97934dff0d2221b7)
2025-09-25 16:23:41 +00:00
Shariq Ansari
bfb0d25765 chore: Norwegian Bokmal translations
(cherry picked from commit f91ac266ca921427fa2d38af4e8d8f847d46e111)
2025-09-25 16:23:41 +00:00
Shariq Ansari
9dd6ffa1e1 chore: Danish translations
(cherry picked from commit 415d5410ba707a59a6cc6a7cf8d0bafc8a6a7e50)
2025-09-25 16:23:41 +00:00
Shariq Ansari
05322e805f chore: Esperanto translations
(cherry picked from commit 9fc20a3078922b45440551343f7fb032d17d814b)
2025-09-25 16:23:40 +00:00
Shariq Ansari
8dc6db3218 chore: Croatian translations
(cherry picked from commit 43dadfe746f3ade875bf5420edca1b3bc92cc372)
2025-09-25 16:23:40 +00:00
Shariq Ansari
1b63384eac chore: Thai translations
(cherry picked from commit 56071d5e0dd520d96b24ce92d9079823921402aa)
2025-09-25 16:23:40 +00:00
Shariq Ansari
37bbbb6b4b chore: Persian translations
(cherry picked from commit b0e79d0aef3a3fe637c6d0d2d734118b095a52a5)
2025-09-25 16:23:40 +00:00
Shariq Ansari
6f0244c2b6 chore: Vietnamese translations
(cherry picked from commit 5848649955c084076afda007e21df1b0940394f6)
2025-09-25 16:23:39 +00:00
Shariq Ansari
e08bc9cd20 chore: Chinese Simplified translations
(cherry picked from commit 3c5ee979f86d9a0cdbd6717c91253622e47e3f8d)
2025-09-25 16:23:39 +00:00
Shariq Ansari
2043157567 chore: Turkish translations
(cherry picked from commit 2acd7476c8e1f92f2747a84666badafe5b204910)
2025-09-25 16:23:39 +00:00
Shariq Ansari
8093a422cd chore: Russian translations
(cherry picked from commit 66c586582836bcbd3210a4cd2e254edf3fc9b9f5)
2025-09-25 16:23:38 +00:00
Shariq Ansari
4bef919d38 chore: Portuguese translations
(cherry picked from commit 103a137af12912bcf388b06a14c84abadbad8979)
2025-09-25 16:23:38 +00:00
Shariq Ansari
874947b8ae chore: Dutch translations
(cherry picked from commit 52cc70d704a284bd41696e67e2c1fb24142dc6ee)
2025-09-25 16:23:38 +00:00
Shariq Ansari
ca90c0406e chore: Hungarian translations
(cherry picked from commit d72dcee7b663d35c83a5658815a1cdd529b445c3)
2025-09-25 16:23:38 +00:00
Shariq Ansari
6bf27d852b chore: Czech translations
(cherry picked from commit b473b27f9ace8d76023b13ec1cf57e81cc487835)
2025-09-25 16:23:37 +00:00
Shariq Ansari
793cb76789 chore: Arabic translations
(cherry picked from commit 8805560144baa224c6f3ac5758e9d3d288e60f45)
2025-09-25 16:23:37 +00:00
Shariq Ansari
ff07054ca3 chore: Spanish translations
(cherry picked from commit 3f0c4e9614d8081344dd8ef213bed525c69a4b1a)
2025-09-25 16:23:37 +00:00
Shariq Ansari
2ee5269d3e chore: French translations
(cherry picked from commit 2b13c3f27704a8b50facb7636f4a82810e843bd6)
2025-09-25 16:23:36 +00:00
Shariq Ansari
e27954da52 chore: German translations
(cherry picked from commit b6fa3bf32b3c21e82917061da94f450e81f48323)
2025-09-25 16:23:36 +00:00
Shariq Ansari
2faa0d0f04 chore: Serbian (Latin) translations
(cherry picked from commit ae9e59aa0002112fa22192d15df43491b1145c8c)
2025-09-25 16:23:36 +00:00
Shariq Ansari
f1664eec2f chore: Bosnian translations
(cherry picked from commit 4533becc620ea06bc61043eb58e8350b90445950)
2025-09-25 16:23:36 +00:00
Shariq Ansari
7f2efea7cb chore: Indonesian translations
(cherry picked from commit 57bd9fe70a6f09d336b8b17dd1215481f2f5d03d)
2025-09-25 16:23:35 +00:00
Shariq Ansari
d2cc6b7c2e chore: Portuguese, Brazilian translations
(cherry picked from commit 013c21a5d1b564632b0383893d4b45512afa9e4c)
2025-09-25 16:23:35 +00:00
Shariq Ansari
1afb6d6827 chore: Swedish translations
(cherry picked from commit 9a780039e589e369f76f4fe9b4e0dff0902bd859)
2025-09-25 16:23:35 +00:00
Shariq Ansari
ccaf136830 chore: Serbian (Cyrillic) translations
(cherry picked from commit 1bd62289dc720edc9515a3677ac377732ae1dc60)
2025-09-25 16:23:34 +00:00
Shariq Ansari
58a41d1b11 chore: Polish translations
(cherry picked from commit f7382f40ac78be3804f34866162f30329f742d76)
2025-09-25 16:23:34 +00:00
Shariq Ansari
777f3ac06c chore: Italian translations
(cherry picked from commit 3c870ce042a7d165ad914f90cf84fd5473ad8243)
2025-09-25 16:23:34 +00:00
Shariq Ansari
105c78e264
Merge pull request #1283 from frappe/mergify/bp/main-hotfix/pr-1282
fix: add validation for mandatory fields in useDocument (backport #1282)
2025-09-25 21:53:09 +05:30
Shariq Ansari
46cc1d2924 build(deps): bump frappeui to 0.1.201
(cherry picked from commit 171060df8ade73f6b9ef4b51945c76604c759299)
2025-09-25 16:22:33 +00:00
Shariq Ansari
ff4ca9fe66 fix: add validation for mandatory fields in useDocument
(cherry picked from commit dbcda4c548270f4b030d819857b1f393fdaadecb)
2025-09-25 16:18:30 +00:00
Shariq Ansari
4989dc0921
Merge pull request #1277 from shariquerik/backport-1125
fix: Bulk Delete "Reference Doctype must be set first" Error (backport #1125)
2025-09-22 16:12:16 +05:30
Shariq Ansari
1e613ebcd1 fix: Bulk Delete 'Reference Doctype must be set first' Error backport (#1125) 2025-09-22 16:04:53 +05:30
Frappe PR Bot
4f8f195d77 chore(release): Bumped to Version 1.53.0 2025-09-22 09:55:37 +00:00
Shariq Ansari
af64b86a04
Merge pull request #1276 from frappe/main-hotfix 2025-09-22 15:25:13 +05:30
Shariq Ansari
7e9bc0524e
Merge pull request #1275 from frappe/mergify/bp/main-hotfix/pr-1266 2025-09-22 15:18:12 +05:30
Shariq Ansari
9d0a0d1d32
Merge pull request #1273 from frappe/mergify/bp/main-hotfix/pr-1272 2025-09-22 15:17:51 +05:30
Shariq Ansari
9c84a8be7f
Merge pull request #1274 from frappe/mergify/bp/main-hotfix/pr-1262 2025-09-22 15:17:42 +05:30
frappe-pr-bot
d24537489e chore: update POT file
(cherry picked from commit 625e472303a4d759024a744bd93bc8d721537a0a)
2025-09-22 09:41:24 +00:00
Shariq Ansari
bd89b3b356 chore: Norwegian Bokmal translations
(cherry picked from commit ce632c69c1e634dc0feed03eec3f4c76370e7dcf)
2025-09-22 09:41:23 +00:00
Shariq Ansari
988fb90ddb chore: Norwegian Bokmal translations
(cherry picked from commit 93ed6fcdddac8a903e470ee35d1cbcca7e9ba5cf)
2025-09-22 09:41:23 +00:00
Shariq Ansari
8018b1766c chore: Norwegian Bokmal translations
(cherry picked from commit e3eff7f78de04f49bb78a3e1401048a42d4bf2eb)
2025-09-22 09:41:23 +00:00
Shariq Ansari
9c4c2a0aca chore: Norwegian Bokmal translations
(cherry picked from commit 394da5e0024dfce029f90346ff695dc7f7a67e5f)
2025-09-22 09:41:23 +00:00
Shariq Ansari
803e639961 build(deps): bump frappeui to 0.1.200
(cherry picked from commit 96c0c99939b30880ddf27b91f3f6b18c95ef3409)
2025-09-22 09:40:21 +00:00
Shariq Ansari
fabd362b2a
Merge pull request #1260 from frappe/mergify/bp/main-hotfix/pr-1256 2025-09-18 15:44:32 +05:30
Shariq Ansari
7dd98733f1
chore: resolved conflict 2025-09-18 15:38:44 +05:30
Shariq Ansari
ee4b7721b0
chore: resolved conflict 2025-09-18 15:37:11 +05:30
Shariq Ansari
95bc551254
chore: resolved conflict 2025-09-18 15:35:03 +05:30
Shariq Ansari
2546bdabb1 refactor: adjust padding and improve layout for Settings component
(cherry picked from commit d687a2eb56142c49b2b776dec55ad533556421f6)
2025-09-18 09:59:25 +00:00
Shariq Ansari
af248964c6 refactor: adjust padding and improve layout for Currency and Forecasting settings components
(cherry picked from commit 1044adc494b0b5b7f347aaf0080914a28be56eb9)
2025-09-18 09:59:25 +00:00
Shariq Ansari
8749f7bfd0 refactor: update styling and improve layout for assignment rules components
(cherry picked from commit 9f95a3a2b2132357708db03b9b4922f356150ff4)
2025-09-18 09:59:25 +00:00
Shariq Ansari
d18618b856 refactor: replace EmailMultiSelect with FormControl for inviting users by email
(cherry picked from commit 69f80903118965f500199f1b3368deb195882699)

# Conflicts:
#	frontend/src/components/Settings/InviteUserPage.vue
2025-09-18 09:59:24 +00:00
Shariq Ansari
ce4af4907a refactor: remove TemplateOption component usage and simplify dropdown options in multiple components
(cherry picked from commit ac34ac9b87b9c671be75401a545e09e0e83ac378)

# Conflicts:
#	frontend/src/components/Settings/Users.vue
2025-09-18 09:59:24 +00:00
Shariq Ansari
84d24a384b refactor: update Vite configuration to support dynamic loading of frappe-ui in development mode
(cherry picked from commit 129f8a00b66d87529c21ef085e66dc7864a3776e)
2025-09-18 09:59:24 +00:00
Shariq Ansari
29d86859d4 revert: create dynamic alias to use components from frontend vue apps
(cherry picked from commit 6328b6941bb620e47cebe82519df3f1453f355ae)
2025-09-18 09:59:23 +00:00
Shariq Ansari
be452fee58 refactor: reduce gap in Brand logo and Favicon sections for improved layout
(cherry picked from commit fbc9e37036d5720948381ca891714d78af001433)
2025-09-18 09:59:23 +00:00
Shariq Ansari
100eec0677 refactor: remove icon-left from Update button in multiple settings components
(cherry picked from commit 149901f6054f000d503ef8940037c13bd2e344f3)
2025-09-18 09:59:23 +00:00
Shariq Ansari
a4d3852c0e feat: Auto update expected deal value based on products value
(cherry picked from commit 7e21a5fee206723cf714f7a8732bb8929aaa57df)
2025-09-18 09:59:23 +00:00
Shariq Ansari
0399fc32be refactor: add ForecastingSettings component and remove GeneralSettingsPage component
(cherry picked from commit f4ff6bbdf306a89b78aab82df972bf55e1e0d82d)
2025-09-18 09:59:22 +00:00
Shariq Ansari
a79192ef4d fix: add auto-update expected deal value checkbox in FCRM settings
(cherry picked from commit 915023317310178d67306bb6d8b48e224e5644ae)
2025-09-18 09:59:22 +00:00
Shariq Ansari
e10ec543a7 refactor: CurrencySettings component
(cherry picked from commit 186584c1ac79170afa4ef8860bff9d3d3d91cadc)
2025-09-18 09:59:22 +00:00
Shariq Ansari
1962b9a103 refactor: update BrandSettings component to improve logo and favicon handling
(cherry picked from commit 3752c611576778f028ba78d6c1ae533a88c6040b)
2025-09-18 09:59:21 +00:00
Shariq Ansari
a3abaa57ec refactor: HomeActions component
(cherry picked from commit a6ecc5cfeda51781286d013cf3a738b8a3adfdc5)
2025-09-18 09:59:21 +00:00
Shariq Ansari
1bf3f7a38c refactor: BrandSettings component
(cherry picked from commit 84e0fe30a9667468ea9ddbb0bc768e3da62620d3)
2025-09-18 09:59:20 +00:00
Shariq Ansari
af81750388 refactor: enhance Settings component structure
(cherry picked from commit 03acea69b130cfdbdc00994c8d9930ad948cb64c)

# Conflicts:
#	frontend/src/components/Settings/Settings.vue
2025-09-18 09:59:20 +00:00
Shariq Ansari
7330a3c2a5 refactor: clean up ImageUploader component and improve label handling
(cherry picked from commit e19f75083147faaf988bcbef448e9d1ddbb9179a)
2025-09-18 09:59:19 +00:00
Shariq Ansari
9e8a4024a5
Merge pull request #1255 from frappe/mergify/bp/main-hotfix/pr-1252
fix: paddings and labels (backport #1252)
2025-09-18 15:27:27 +05:30
Shariq Ansari
7ef00965fa
Merge branch 'main-hotfix' into mergify/bp/main-hotfix/pr-1252 2025-09-18 15:21:52 +05:30
Shariq Ansari
97925aae15
Merge pull request #1259 from frappe/mergify/bp/main-hotfix/pr-1257 2025-09-18 15:17:19 +05:30
Shariq Ansari
0b75228722 chore: Portuguese translations
(cherry picked from commit fca831b92e633f7a7f6cdd09f66d83bac19e2590)
2025-09-18 09:42:12 +00:00
Shariq Ansari
a360fa774b
Merge pull request #1258 from frappe/mergify/bp/main-hotfix/pr-1206 2025-09-18 15:11:28 +05:30
Shariq Ansari
4601b56ee1
chore: resolved conflict 2025-09-18 15:05:35 +05:30
Pratik Badhe
d985a44291 feat: add assignment rule
(cherry picked from commit 0c5684905f44af211189bf674735b046858a5b86)

# Conflicts:
#	frontend/components.d.ts
#	yarn.lock
2025-09-18 09:19:54 +00:00
Pratik Badhe
ce66705e9c revert: yarn.lock file
(cherry picked from commit 41ef219d0abd0c0036d7697dc5a8b8ab78a81344)
2025-09-17 06:47:25 +00:00
Pratik Badhe
004923419c fix: paddings and labels
(cherry picked from commit db577afc568b56b49846773b16b638e0cf1444fa)

# Conflicts:
#	frontend/src/components/Settings/AssignmentRules/AssigneeRules.vue
#	frontend/src/components/Settings/AssignmentRules/AssignmentRuleView.vue
#	frontend/src/components/Settings/AssignmentRules/AssignmentRules.vue
2025-09-17 06:47:25 +00:00
Shariq Ansari
49ed1ac174
Merge pull request #1254 from frappe/mergify/bp/main-hotfix/pr-1253 2025-09-17 11:55:38 +05:30
Shariq Ansari
a7dd1e9bf6 chore: Norwegian Bokmal translations
(cherry picked from commit b6e3cdfc378c9ab6322e6148d28387e5d399310c)
2025-09-17 06:08:01 +00:00
Shariq Ansari
4cfd0022f4 chore: Danish translations
(cherry picked from commit c0171c0555fe7091102b12cd2ccd8ec714dbe34d)
2025-09-17 06:08:00 +00:00
Shariq Ansari
fc3d8cd94d chore: Esperanto translations
(cherry picked from commit 6f154e191a816c118ffc190a36277ea9235eedc3)
2025-09-17 06:08:00 +00:00
Shariq Ansari
5473a93b5e chore: Croatian translations
(cherry picked from commit 552e500a31bca989d7b4554cfc0aa0015635098c)
2025-09-17 06:08:00 +00:00
Shariq Ansari
57d306ea1f chore: Thai translations
(cherry picked from commit bf6940a6ff7cd972c384a050068aaa2835bc371a)
2025-09-17 06:07:59 +00:00
Shariq Ansari
7c324bd07f chore: Persian translations
(cherry picked from commit dc9b07b02a5ea4443967d3261781d2786e7ff810)
2025-09-17 06:07:59 +00:00
Shariq Ansari
09421217b4 chore: Vietnamese translations
(cherry picked from commit 0a45094c33db76bea8606c02b2b0985e6e35e34f)
2025-09-17 06:07:59 +00:00
Shariq Ansari
630dfcd0e7 chore: Chinese Simplified translations
(cherry picked from commit 247d8e043e548d30ffc4494544cdf7e95bec94e1)
2025-09-17 06:07:58 +00:00
Shariq Ansari
b999a375b3 chore: Turkish translations
(cherry picked from commit 73a1ecd418e0ca1ba40442aa0338b7f6853d0650)
2025-09-17 06:07:58 +00:00
Shariq Ansari
b5f5a3b5d5 chore: Russian translations
(cherry picked from commit 77e7bb011b5357465f6565eeddddd4ec160c1d3c)
2025-09-17 06:07:57 +00:00
Shariq Ansari
814d39572a chore: Portuguese translations
(cherry picked from commit 9233e77ab8376301a61c56d4ee072fb3c4caea4b)
2025-09-17 06:07:57 +00:00
Shariq Ansari
6fc4c0699a chore: Dutch translations
(cherry picked from commit 32e5d56ef19da5c0577334992a43d3c0db761700)
2025-09-17 06:07:57 +00:00
Shariq Ansari
50ea06a568 chore: Hungarian translations
(cherry picked from commit cea6b6c6b4bfe87e6c533aadba632f60081853bc)
2025-09-17 06:07:56 +00:00
Shariq Ansari
daf0ddaab4 chore: Czech translations
(cherry picked from commit 2d636d7ffb252e52352e0883747c6fb158d42774)
2025-09-17 06:07:56 +00:00
Shariq Ansari
70107a4836 chore: Arabic translations
(cherry picked from commit 9d9caf2856b5fd1c1f5bc88024292a2dea3dd1f3)
2025-09-17 06:07:56 +00:00
Shariq Ansari
f2e6380d3e chore: Spanish translations
(cherry picked from commit 4ff4f3c5b53fe6ea60623894770ecad3b2289441)
2025-09-17 06:07:56 +00:00
Shariq Ansari
eed1e23b5b chore: French translations
(cherry picked from commit 8167e1388da8693ab2d14dba876d7092a40d1875)
2025-09-17 06:07:55 +00:00
Shariq Ansari
1bb75dd911 chore: German translations
(cherry picked from commit 8e3cf3846aad4c72ff8d1b53a662d95565ce227a)
2025-09-17 06:07:55 +00:00
Shariq Ansari
1086ce406f chore: Serbian (Latin) translations
(cherry picked from commit 2d8ada04c869cc4f0652c3d2e2946820e1b89335)
2025-09-17 06:07:55 +00:00
Shariq Ansari
39c5497363 chore: Bosnian translations
(cherry picked from commit 4fba2353cffcab5e223318b74830390046ee1deb)
2025-09-17 06:07:54 +00:00
Shariq Ansari
4bc31431e7 chore: Indonesian translations
(cherry picked from commit f251d83e97cdca93447de491e228e0648f16c7f0)
2025-09-17 06:07:54 +00:00
Shariq Ansari
fe290877e4 chore: Portuguese, Brazilian translations
(cherry picked from commit 283b34662e6da88c68273cd64c708e63a7aabadb)
2025-09-17 06:07:54 +00:00
Shariq Ansari
e4bdc0586e chore: Swedish translations
(cherry picked from commit 9bcfcf4ac722caf126cf311079c3220590e8c91d)
2025-09-17 06:07:53 +00:00
Shariq Ansari
695f9e1303 chore: Serbian (Cyrillic) translations
(cherry picked from commit d80bbcd33d99872ffe28cc334c3c523ac775506e)
2025-09-17 06:07:53 +00:00
Shariq Ansari
98747bdc2a chore: Polish translations
(cherry picked from commit 42ee5ea64df69c172cd683aa9e1169969267158b)
2025-09-17 06:07:53 +00:00
Shariq Ansari
16ed1ad060 chore: Italian translations
(cherry picked from commit 1472a7f33d50686df2ff5c978682d3a693b5d674)
2025-09-17 06:07:52 +00:00
Shariq Ansari
ff312d964b
Merge pull request #1251 from frappe/main-hotfix 2025-09-16 15:23:38 +05:30
Shariq Ansari
49d7af5548 build(deps): bump frappeui to 0.1.197 2025-09-16 14:51:32 +05:30
Shariq Ansari
a30d21c346
Merge pull request #1250 from frappe/mergify/bp/main-hotfix/pr-1242 2025-09-16 14:25:58 +05:30
Shariq Ansari
f459bd57ba
Merge pull request #1249 from frappe/mergify/bp/main-hotfix/pr-1245 2025-09-16 14:25:50 +05:30
Shariq Ansari
b4d89e1a5a chore: Danish translations
(cherry picked from commit 2e5f4a9d22f615ff8f57afd4cccb763fb3b0d1da)
2025-09-16 08:50:23 +00:00
Shariq Ansari
25bc9d8acb chore: Persian translations
(cherry picked from commit 100d01334a4fa5d9b9c686b27a6c794fc1e8cd35)
2025-09-16 08:50:22 +00:00
Shariq Ansari
568477f9c7 chore: Portuguese translations
(cherry picked from commit 03ab96d94f49599ccc0a2ca4fe4045540d59403a)
2025-09-16 08:50:22 +00:00
Shariq Ansari
9c04ade20d chore: Norwegian Bokmal translations
(cherry picked from commit 6f640f5eee07558b133fe1acea6b26e9f23783c1)
2025-09-16 08:50:22 +00:00
Shariq Ansari
7940211fad chore: Norwegian Bokmal translations
(cherry picked from commit 376917bc75086608fcd774289d119c6a6adb2d32)
2025-09-16 08:50:21 +00:00
Shariq Ansari
df0968ed67 chore: Portuguese translations
(cherry picked from commit 54753d3274a5e75dd684efafca91517f04104620)
2025-09-16 08:50:21 +00:00
Shariq Ansari
89462e63cb chore: Turkish translations
(cherry picked from commit 3c3108a9c19bab39ca67bb7efbc8e299ccfcc5ea)
2025-09-16 08:50:21 +00:00
Shariq Ansari
23c53ffa9a chore: Norwegian Bokmal translations
(cherry picked from commit e0cfae1eb3fae321bf187c2e8bae9875e7409bb8)
2025-09-16 08:50:21 +00:00
Shariq Ansari
ae3df8d391 chore: Norwegian Bokmal translations
(cherry picked from commit fa03245effea3cabe2e536c99ec4ef65460d80c4)
2025-09-16 08:50:20 +00:00
Shariq Ansari
2d51933ceb chore: Serbian (Latin) translations
(cherry picked from commit f253392ba74c28f78357fe70d886db6eaf73128f)
2025-09-16 08:50:20 +00:00
Shariq Ansari
a7958dc2a2 chore: Serbian (Cyrillic) translations
(cherry picked from commit 6e608d845b99b959bf18232abf0235a87b2b274f)
2025-09-16 08:50:20 +00:00
frappe-pr-bot
1c4f78b01c chore: update POT file
(cherry picked from commit 1627cf1e5488f596e463b6253855cf8eff17064f)
2025-09-16 08:49:19 +00:00
Shariq Ansari
2722ef6cad
Merge pull request #1241 from frappe/mergify/bp/main-hotfix/pr-1240 2025-09-09 14:30:02 +05:30
Shariq Ansari
ac7d3907c2 chore: Norwegian Bokmal translations
(cherry picked from commit ffd2452675e3710e5e64535d6b29faff736c1607)
2025-09-09 08:57:46 +00:00
Frappe PR Bot
17b7c6ecef chore(release): Bumped to Version 1.52.11 2025-09-08 14:20:41 +00:00
Shariq Ansari
8d7a155d78
Merge pull request #1239 from frappe/main-hotfix 2025-09-08 19:49:39 +05:30
Shariq Ansari
6dc85ad1b2
Merge branch 'main' into main-hotfix 2025-09-08 19:42:43 +05:30
Shariq Ansari
ac98c1a090
Merge pull request #1238 from frappe/mergify/bp/main-hotfix/pr-1237 2025-09-08 14:53:07 +05:30
Shariq Ansari
90a6bde438 chore: Norwegian Bokmal translations
(cherry picked from commit 097c58b991eac4253b637f535d13132bf6d21dc5)
2025-09-08 05:50:47 +00:00
Shariq Ansari
5fea7bf0e2 chore: Danish translations
(cherry picked from commit 64bf702b62d55eed433106bfc6b00887a58c29cb)
2025-09-08 05:50:46 +00:00
Shariq Ansari
1031e9c4ec chore: Esperanto translations
(cherry picked from commit 7e27e9f45ef72862626dd756cbf3cf50730ddce2)
2025-09-08 05:50:46 +00:00
Shariq Ansari
c6e4b9b5d3 chore: Croatian translations
(cherry picked from commit ee19b344ec333b53e0a585d99465cf908d58318e)
2025-09-08 05:50:46 +00:00
Shariq Ansari
f2a4b9ec56 chore: Thai translations
(cherry picked from commit eb70553fea56eb054e28676287323367b1aea3e4)
2025-09-08 05:50:46 +00:00
Shariq Ansari
14a1af4455 chore: Persian translations
(cherry picked from commit 9e4d268b504220f3a98a1411b9d0c0961e01f9b5)
2025-09-08 05:50:45 +00:00
Shariq Ansari
e3ab227124 chore: Vietnamese translations
(cherry picked from commit d92c25ab4ea769593ed4252a4058a85713b7d7ba)
2025-09-08 05:50:45 +00:00
Shariq Ansari
5f6cc26126 chore: Chinese Simplified translations
(cherry picked from commit 9975be4ff7984ccd663edf2544374319ff15e965)
2025-09-08 05:50:45 +00:00
Shariq Ansari
8051fd1f99 chore: Turkish translations
(cherry picked from commit 2442f6f2adc51a5a00a96798a20d0d856d24d85e)
2025-09-08 05:50:44 +00:00
Shariq Ansari
1fc98f619c chore: Russian translations
(cherry picked from commit e39a20f652a5900598eed1cb70c049a13ac38bec)
2025-09-08 05:50:44 +00:00
Shariq Ansari
5921af8c0b chore: Portuguese translations
(cherry picked from commit dcca47f3cad050cd573f40b648fd70f0baf6a704)
2025-09-08 05:50:44 +00:00
Shariq Ansari
fe505d33d2 chore: Dutch translations
(cherry picked from commit df8aaea3745a6f83baca39860afaaac3b91045a0)
2025-09-08 05:50:44 +00:00
Shariq Ansari
300f0b24e2 chore: Hungarian translations
(cherry picked from commit c3ac80afa8c74217a100c7b5d0ee24e1b738f62d)
2025-09-08 05:50:43 +00:00
Shariq Ansari
b7c26e35e9 chore: Czech translations
(cherry picked from commit 8d59359ef5bf29a4b46163f1fa118aa13d6ddf2b)
2025-09-08 05:50:43 +00:00
Shariq Ansari
4c7c8b915a chore: Arabic translations
(cherry picked from commit 53202f4a5b07eba3afc408736abc077eb4461a44)
2025-09-08 05:50:43 +00:00
Shariq Ansari
d80feb1e77 chore: Spanish translations
(cherry picked from commit 792db2725229ab4372b0349995acea0ecc313ee9)
2025-09-08 05:50:43 +00:00
Shariq Ansari
2a8c7307f0 chore: French translations
(cherry picked from commit c9bcbcf1d0a4e15ca65a5f77ef046156531b9128)
2025-09-08 05:50:42 +00:00
Shariq Ansari
0683d93621 chore: German translations
(cherry picked from commit 79a0c02f03b092f4259f63ec92d7372ee1cdafb6)
2025-09-08 05:50:42 +00:00
Shariq Ansari
5ce2fcd368 chore: Serbian (Latin) translations
(cherry picked from commit 2a5dbfb75d382c73ad94725030ae509049abe3bc)
2025-09-08 05:50:42 +00:00
Shariq Ansari
5372fdcaf1 chore: Bosnian translations
(cherry picked from commit b7443ff1bb90770e15af51b42a37e0dc35fb2d8a)
2025-09-08 05:50:41 +00:00
Shariq Ansari
9f46bbd25d chore: Indonesian translations
(cherry picked from commit 5ee9d5787a542b27d2059f76edc19c4657c7886b)
2025-09-08 05:50:41 +00:00
Shariq Ansari
87e82ce39e chore: Portuguese, Brazilian translations
(cherry picked from commit 426dc836ca4eb324ee1929bec06c646ea04095ab)
2025-09-08 05:50:41 +00:00
Shariq Ansari
443aeddca0 chore: Swedish translations
(cherry picked from commit d5287103797eebe59f2f821eb5ad9dafbc8cdadc)
2025-09-08 05:50:41 +00:00
Shariq Ansari
dc7d5f57b8 chore: Serbian (Cyrillic) translations
(cherry picked from commit 0a4cfa6055da2820f5ca9a52f25979f0e3cfd829)
2025-09-08 05:50:40 +00:00
Shariq Ansari
1cbd633e5b chore: Polish translations
(cherry picked from commit 1ca85157abc1f4ea412f34163469d3451fbab998)
2025-09-08 05:50:40 +00:00
Shariq Ansari
cf58a634e9 chore: Italian translations
(cherry picked from commit d8162a1dc48705ab7d9b89f0f9dacf1422a80c02)
2025-09-08 05:50:40 +00:00
Frappe PR Bot
b118e75bec chore(release): Bumped to Version 1.52.10 2025-09-07 14:02:13 +00:00
Shariq Ansari
2b1048fd83
Merge pull request #1236 from frappe/mergify/bp/main/pr-1234
fix: Organization is not getting renamed (backport #1234)
2025-09-07 19:31:08 +05:30
Shariq Ansari
7468f19b48
Merge pull request #1235 from frappe/mergify/bp/main-hotfix/pr-1234
fix: Organization is not getting renamed (backport #1234)
2025-09-07 19:30:57 +05:30
Shariq Ansari
f994dd36a9 fix: remove unnecessary class from Button component in TaskModal and add click.stop to Notes dropdown
(cherry picked from commit 30d95a6582cf8d5ba8e06e6d94e78b54c82e57a3)
2025-09-07 13:55:59 +00:00
Shariq Ansari
dc98613296 fix: add 'interactjs' to optimizeDeps include list in vite.config.js
(cherry picked from commit 24b580150af1e51db30c3c9fac8138bc62dd8a05)
2025-09-07 13:55:58 +00:00
Shariq Ansari
f132a46206 fix: update organization logo handling and add beforeFieldChange functionality to rename organization
(cherry picked from commit 1b7af2096f6bfc18094ce727e3e43754c279e51b)
2025-09-07 13:55:58 +00:00
Shariq Ansari
cfeac13c9c fix: remove unnecessary class from Button component in TaskModal and add click.stop to Notes dropdown
(cherry picked from commit 30d95a6582cf8d5ba8e06e6d94e78b54c82e57a3)
2025-09-07 13:55:55 +00:00
Shariq Ansari
b82dc0473a fix: add 'interactjs' to optimizeDeps include list in vite.config.js
(cherry picked from commit 24b580150af1e51db30c3c9fac8138bc62dd8a05)
2025-09-07 13:55:55 +00:00
Shariq Ansari
8f0e8f3f52 fix: update organization logo handling and add beforeFieldChange functionality to rename organization
(cherry picked from commit 1b7af2096f6bfc18094ce727e3e43754c279e51b)
2025-09-07 13:55:54 +00:00
Shariq Ansari
7a9da275da
Merge pull request #1233 from frappe/mergify/bp/main-hotfix/pr-1230 2025-09-07 18:07:30 +05:30
Shariq Ansari
cc25feea09 chore: Norwegian Bokmal translations
(cherry picked from commit 891d78c3b655a473c7215002f1c0fb35f92de89f)
2025-09-07 12:30:47 +00:00
Shariq Ansari
b64058bd10 chore: Norwegian Bokmal translations
(cherry picked from commit 4baee8351b911d47fad88aaa528254766e424e19)
2025-09-07 12:30:47 +00:00
Shariq Ansari
b6af543243
Merge pull request #1232 from frappe/mergify/bp/main/pr-1231 2025-09-07 17:59:11 +05:30
Shariq Ansari
7bcee291c7
chore: resolved conflict 2025-09-07 17:58:17 +05:30
frappe-pr-bot
570a45eeaf chore: update POT file
(cherry picked from commit 591076bf2778d5f98e4023665fcd8b84e7747b2f)

# Conflicts:
#	crm/locale/main.pot
2025-09-07 12:20:39 +00:00
Shariq Ansari
dcadd3d0c1
Merge pull request #1228 from frappe/mergify/bp/main-hotfix/pr-1224 2025-09-05 16:18:50 +05:30
Shariq Ansari
8d4975554d chore: Portuguese translations
(cherry picked from commit 023d949577a74af8ebe0d61b95da73ad988a64e0)
2025-09-05 10:48:09 +00:00
Shariq Ansari
4bf8c8d0b8
Merge pull request #1227 from frappe/mergify/bp/main-hotfix/pr-1226
fix: if contact email is updated it is updating previously opened contact (backport #1226)
2025-09-05 16:15:01 +05:30
Shariq Ansari
0d9264e5e2
chore: resolved conflict 2025-09-05 15:53:57 +05:30
Shariq Ansari
068f303448
chore: resolved conflict 2025-09-05 15:51:48 +05:30
Shariq Ansari
e8e4367eb7
chore: resolved conflict 2025-09-05 15:50:09 +05:30
Shariq Ansari
afadf9f8f4 fix: if contact email is updated it is updating previously opened contact
(cherry picked from commit 50708ebe32df130a4c6c5f678b5b9d0e85ccfa66)

# Conflicts:
#	frontend/components.d.ts
#	frontend/src/components/SidePanelLayout.vue
#	frontend/src/pages/Contact.vue
2025-09-05 10:16:18 +00:00
Shariq Ansari
8ab6da55de
Merge pull request #1223 from frappe/mergify/bp/main-hotfix/pr-1220 2025-09-04 17:54:42 +05:30
Shariq Ansari
b066eb8c75
Merge pull request #1222 from frappe/mergify/bp/main-hotfix/pr-1221
fix: address creation not returning to organization modal (backport #1221)
2025-09-04 17:53:54 +05:30
Shariq Ansari
c33f2e936a chore: Norwegian Bokmal translations
(cherry picked from commit 0cd527f6ef9b5409d1fb3c0ba6874302a4268704)
2025-09-04 12:22:34 +00:00
Shariq Ansari
2f02b8ccfd chore: Danish translations
(cherry picked from commit fead8c38767d8ccd8a81a77f9d04036354a452b5)
2025-09-04 12:22:33 +00:00
Shariq Ansari
9e9b0f7266 chore: Esperanto translations
(cherry picked from commit 1e6270df44b9d9b478de7c7cd9e44c634d2bffd2)
2025-09-04 12:22:33 +00:00
Shariq Ansari
148e6ef8bb chore: Croatian translations
(cherry picked from commit 7c9e9b954da6539744e6886aa8beb00b94748a78)
2025-09-04 12:22:33 +00:00
Shariq Ansari
00398b188c chore: Thai translations
(cherry picked from commit 6b2a1e7ff1f36fdc9ea4365fb44ff9575c2a7fbf)
2025-09-04 12:22:32 +00:00
Shariq Ansari
80e43864b7 chore: Persian translations
(cherry picked from commit 4aa506985faf95608edc9cf35a523648bab98574)
2025-09-04 12:22:32 +00:00
Shariq Ansari
9a9b91b76d chore: Vietnamese translations
(cherry picked from commit 496659af0a5a825aed132a46cc93e1e9c2612d79)
2025-09-04 12:22:32 +00:00
Shariq Ansari
d555222ebb chore: Chinese Simplified translations
(cherry picked from commit 9669b6d54c8e25345acd30677f0fc975352d0983)
2025-09-04 12:22:32 +00:00
Shariq Ansari
222ba09c67 chore: Turkish translations
(cherry picked from commit d406f7345cb08dbd1fc525aff638170c66430ef0)
2025-09-04 12:22:31 +00:00
Shariq Ansari
0c8a3edf5e chore: Russian translations
(cherry picked from commit f838ef56a66a6cf62a283d83982c067cfedf1a60)
2025-09-04 12:22:31 +00:00
Shariq Ansari
c44f7d5834 chore: Portuguese translations
(cherry picked from commit 77c5cb40e9f5abb32e38d5004dcdf1cac291e30a)
2025-09-04 12:22:31 +00:00
Shariq Ansari
f072fc992c chore: Dutch translations
(cherry picked from commit 0e1a4f00061f52e6b3e86b8a636d98a0bfc9addc)
2025-09-04 12:22:30 +00:00
Shariq Ansari
092310846c chore: Hungarian translations
(cherry picked from commit c4b5c56fe4daadc619445c3e8a29080b6f46fae7)
2025-09-04 12:22:30 +00:00
Shariq Ansari
eb00a7c692 chore: Czech translations
(cherry picked from commit 9066ed068826937aee7128c90e1f539c7aefb49d)
2025-09-04 12:22:30 +00:00
Shariq Ansari
8a7ed1e8f1 chore: Arabic translations
(cherry picked from commit 9a189aa5860f5069f2c993763297aa4d7d7381e7)
2025-09-04 12:22:29 +00:00
Shariq Ansari
a852e33605 chore: Spanish translations
(cherry picked from commit aa28206f572b0a1303a638f4af9c4290c472e4ec)
2025-09-04 12:22:29 +00:00
Shariq Ansari
7f3732f0e0 chore: French translations
(cherry picked from commit 628be7cb7cea5e50954518229ede04b6ad58eb1d)
2025-09-04 12:22:29 +00:00
Shariq Ansari
75a9bd290c chore: German translations
(cherry picked from commit b74f92c86e8d26798d3ead8748cef245e643f26b)
2025-09-04 12:22:28 +00:00
Shariq Ansari
687c1d362c chore: Serbian (Latin) translations
(cherry picked from commit 9190974293d715158d1ea6186b3588e7b74d7287)
2025-09-04 12:22:28 +00:00
Shariq Ansari
e771a63640 chore: Bosnian translations
(cherry picked from commit ffae4b10b9284f68ecbd478712148443fd3bbdc6)
2025-09-04 12:22:28 +00:00
Shariq Ansari
e87785fac5 chore: Indonesian translations
(cherry picked from commit b64baa239095fb34691f6713cf9ad8aede2e7f57)
2025-09-04 12:22:27 +00:00
Shariq Ansari
c84da0c7b4 chore: Portuguese, Brazilian translations
(cherry picked from commit 87c4d38c7787e7a227ac47490792ccdddeddc796)
2025-09-04 12:22:27 +00:00
Shariq Ansari
aeb4590a6f chore: Swedish translations
(cherry picked from commit bf32cbd3e8dacc2209aa59ba7d53dc90a0a02330)
2025-09-04 12:22:27 +00:00
Shariq Ansari
d6567c7f01 chore: Serbian (Cyrillic) translations
(cherry picked from commit 6d929d0e7e5dc2c6039383e554bbfa9012c0fb47)
2025-09-04 12:22:26 +00:00
Shariq Ansari
8083fc46a8 chore: Polish translations
(cherry picked from commit df31d8820cf51aa4177610c2cfa6b4aa51879e87)
2025-09-04 12:22:26 +00:00
Shariq Ansari
7f6a20ff17 chore: Italian translations
(cherry picked from commit 4bd5e5a9cc2e4158bb71bbd367f4c3bd2ff219c5)
2025-09-04 12:22:26 +00:00
Shariq Ansari
95df85f676 chore: removed commented code
(cherry picked from commit f9f405cc00e156a64df045dc6df700bb6ece929f)
2025-09-04 12:21:26 +00:00
Aftab Shaikh
728150e324 fix: address creation not returning to organization modal
(cherry picked from commit 32993af090f2e741254ffb2ce8241ed11122f11b)
2025-09-04 12:21:25 +00:00
Shariq Ansari
2ac8a06bae
Merge pull request #1218 from frappe/mergify/bp/main-hotfix/pr-1192
fix: Popup doesn't close after deletion (backport #1192)
2025-09-03 12:48:05 +05:30
Shariq Ansari
2f56af0384 chore: indentation fix
(cherry picked from commit 899481d752209687c26390e8a037dc7c139891fa)
2025-09-03 07:17:24 +00:00
Shariq Ansari
06d647dd72 chore: indentation fix
(cherry picked from commit 8a1ebeb52d7682e00e6626990408d81386d5093a)
2025-09-03 07:17:24 +00:00
Yashpal Patle
ee964637ac fixed popup deletion
(cherry picked from commit b55bf0918fed0c5c997e12f983616f7f1f152567)
2025-09-03 07:17:24 +00:00
Shariq Ansari
4f113fab91
Merge pull request #1217 from frappe/mergify/bp/main-hotfix/pr-1198 2025-09-03 12:28:51 +05:30
Shariq Ansari
8be5535a2b chore: removed comment
(cherry picked from commit 8d0d234ac131b52266bdebb248b232b4923f97c0)
2025-09-03 06:40:30 +00:00
Shariq Ansari
c0050dda71 chore: removed comment
(cherry picked from commit 7fda0db51b75f3d4b2b79db47640bb8fdfac26df)
2025-09-03 06:40:30 +00:00
anup-dh
56eecdd260 Added support for outgoing whatsapp messages from other apps
made changes so that:
1. whatsapp message is created (app: frappe_whatsapp) even if no phone number match is found in CRM Deal & CRM Lead.
2. Also assigns reference doctype and name for Outgoing whatsappe messages which are not sent via CRM app.
3. added a "if doctype and" check to make sure notify_agent does not fail whatsapp message creation if whatsapp message is being created as per step 1.

(cherry picked from commit 486a06baf0d77cf27c75b9303750969c12c47743)
2025-09-03 06:40:30 +00:00
Shariq Ansari
ead86735d4
Merge pull request #1216 from frappe/mergify/bp/main-hotfix/pr-1202 2025-09-03 12:02:01 +05:30
Shariq Ansari
76f6da88f3
Merge pull request #1215 from frappe/mergify/bp/main-hotfix/pr-1204 2025-09-03 12:01:54 +05:30
Shariq Ansari
e252ac8370 chore: Norwegian Bokmal translations
(cherry picked from commit 33a7f50fed852b6d2052c0f40ef85a2438b8aff6)
2025-09-03 06:25:24 +00:00
Shariq Ansari
03b920570e chore: Danish translations
(cherry picked from commit 6ca2f83c0564e1f21953526d241e1bb00d3d040e)
2025-09-03 06:25:24 +00:00
Shariq Ansari
da4e84d6d0 chore: Hungarian translations
(cherry picked from commit c4f76cea6cdb5a8f9d636ef50f2e8fa8a477dca0)
2025-09-03 06:25:24 +00:00
Shariq Ansari
2f90a075fc chore: Norwegian Bokmal translations
(cherry picked from commit 22369825e8ca2ee1b61ec2c2592d10a723deeb92)
2025-09-03 06:25:24 +00:00
Shariq Ansari
de85fa5d5b chore: Hungarian translations
(cherry picked from commit 27b286c6dee73edc607baca4143f00495d484ca2)
2025-09-03 06:25:23 +00:00
Shariq Ansari
e43500887f chore: Norwegian Bokmal translations
(cherry picked from commit 3fb888561b52e607265b81bb9a56f7afbd5879fd)
2025-09-03 06:25:23 +00:00
Shariq Ansari
8f69a49e2c chore: Norwegian Bokmal translations
(cherry picked from commit 50bf6be95fffc7f382d7ca50ba0927105fefd9cd)
2025-09-03 06:25:23 +00:00
frappe-pr-bot
31cbe78320 chore: update POT file
(cherry picked from commit f2f0a4ba2befc88be6b4ee4cd35cc9f32393d5e0)
2025-09-03 06:25:19 +00:00
Shariq Ansari
fa85c61a0a
Merge pull request #1197 from frappe/mergify/bp/main-hotfix/pr-1196
chore: sync translations from crowdin (backport #1196)
2025-08-29 18:56:18 +05:30
Shariq Ansari
e87e1ad61d chore: Norwegian Bokmal translations
(cherry picked from commit 84aacb071703a988eaddbc7b2033e0d7c7a0db95)
2025-08-29 07:45:27 +00:00
Shariq Ansari
bd75fed217 chore: Danish translations
(cherry picked from commit 4c1a4f956e736ae1cfae529018d798448ec44812)
2025-08-29 07:45:27 +00:00
Shariq Ansari
1ede125c80 chore: Swedish translations
(cherry picked from commit 9f1d75817e197e987a37665771bd00b51894b341)
2025-08-29 07:45:26 +00:00
Shariq Ansari
e1e2049b1f
Merge pull request #1193 from frappe/mergify/bp/main-hotfix/pr-1191 2025-08-28 12:10:42 +05:30
Shariq Ansari
32d9e1e2ba chore: Norwegian Bokmal translations
(cherry picked from commit 1706c05f931a7be63d4b9720d627609550cd16b0)
2025-08-28 06:38:27 +00:00
Shariq Ansari
ea5b0fdacd chore: Danish translations
(cherry picked from commit f3bd3de81ce6078151223075cc61c01d197cc070)
2025-08-28 06:38:27 +00:00
Shariq Ansari
a7374bedb2 chore: Croatian translations
(cherry picked from commit 91187f4db0118c7508ec0a4b7c653bb4fbf43451)
2025-08-28 06:38:27 +00:00
Shariq Ansari
5b7437d36a chore: Thai translations
(cherry picked from commit 0d5ad337f66a81002e89bcb60b707336547c2ee0)
2025-08-28 06:38:26 +00:00
Shariq Ansari
8fca1842c2 chore: Persian translations
(cherry picked from commit d3fa9cf98ae49037cebfba38941b081f6ed3eaeb)
2025-08-28 06:38:26 +00:00
Shariq Ansari
2473cf88ef chore: Turkish translations
(cherry picked from commit 2251d4671108790981170e4b4c637a244337a908)
2025-08-28 06:38:26 +00:00
Shariq Ansari
4de04d6760 chore: Spanish translations
(cherry picked from commit 962418c37dde49ffaebf5dca17a5218b5ce89fdc)
2025-08-28 06:38:26 +00:00
Shariq Ansari
f4dc6f8338 chore: German translations
(cherry picked from commit 1d633eabdc8203ec5ac42f49ec4278d0decc09c8)
2025-08-28 06:38:25 +00:00
Shariq Ansari
df5ee5a50c chore: Bosnian translations
(cherry picked from commit 5a0e68b0e8ed5d9399ad0e6815c7eb66f84c1a73)
2025-08-28 06:38:25 +00:00
Shariq Ansari
7b4a3dee6e chore: Portuguese, Brazilian translations
(cherry picked from commit 76f984325111e093cd53399720f174cd7870b2ce)
2025-08-28 06:38:25 +00:00
Shariq Ansari
3dd6c5d1ed chore: Polish translations
(cherry picked from commit 1a6a1854fc60c7eda58db58cdc62bddf33807565)
2025-08-28 06:38:24 +00:00
Shariq Ansari
bc7a148999 chore: Esperanto translations
(cherry picked from commit 5f9fb5a68f65e1f32c1d9667b370f6b7f9bbfdac)
2025-08-28 06:38:24 +00:00
Shariq Ansari
f3f0322003 chore: Croatian translations
(cherry picked from commit 469177182a4920054425f2b83dc2512081000ec9)
2025-08-28 06:38:24 +00:00
Shariq Ansari
aa128a3411 chore: Thai translations
(cherry picked from commit a72e580e1f84196328dd3ce7b2ec3c494b0eda3c)
2025-08-28 06:38:24 +00:00
Shariq Ansari
57f74dbbff chore: Persian translations
(cherry picked from commit 9c88ba879db04576f9f648f11f6ef06d3a237be0)
2025-08-28 06:38:23 +00:00
Shariq Ansari
88b9c6af1d chore: Vietnamese translations
(cherry picked from commit 9d45dea8b304ffb5b071fd6395a3b25fcb22e1ff)
2025-08-28 06:38:23 +00:00
Shariq Ansari
243832812f chore: Chinese Simplified translations
(cherry picked from commit f1732780ccd71da4236d13cc8151b85bf9e308ce)
2025-08-28 06:38:23 +00:00
Shariq Ansari
be09a8fe30 chore: Turkish translations
(cherry picked from commit ae70eee7e0748b0111f471a7812d88ca05858952)
2025-08-28 06:38:23 +00:00
Shariq Ansari
f5e54eefef chore: Russian translations
(cherry picked from commit 03277e240ef2728ac7c0a2cff2d03c6ae3e45a2b)
2025-08-28 06:38:22 +00:00
Shariq Ansari
867da93a39 chore: Portuguese translations
(cherry picked from commit 510f7301fd6ad53cd3c51cec8937cd708ee3704b)
2025-08-28 06:38:22 +00:00
Shariq Ansari
580f61ab71 chore: Dutch translations
(cherry picked from commit 32f42a4009ae6f5a6e87771675c4dfe8b9673d98)
2025-08-28 06:38:22 +00:00
Shariq Ansari
b55011a58e chore: Hungarian translations
(cherry picked from commit 267016cff92a5c1acd04999d086e9b72bc79f6e4)
2025-08-28 06:38:21 +00:00
Shariq Ansari
a8504a910e chore: Czech translations
(cherry picked from commit fc02800a359195f34eb71f1fb2ff92abfa2aa867)
2025-08-28 06:38:21 +00:00
Shariq Ansari
ffc048977f chore: Arabic translations
(cherry picked from commit b33f09c76b494de0205de2822f3b75f0360c8a88)
2025-08-28 06:38:21 +00:00
Shariq Ansari
212709782a chore: Spanish translations
(cherry picked from commit 2d68d1d29aa172a8ea393066c17b6a27ffdf6dc3)
2025-08-28 06:38:21 +00:00
Shariq Ansari
9fb0d3175d chore: French translations
(cherry picked from commit ec14798d9c2efe6ba9dfb758cbc5e8bb39d1fd4a)
2025-08-28 06:38:20 +00:00
Shariq Ansari
4839298ba4 chore: German translations
(cherry picked from commit a2e438ceeae080bf88cd81c53f2bd7a31132153f)
2025-08-28 06:38:20 +00:00
Shariq Ansari
b40c72b95c chore: Serbian (Latin) translations
(cherry picked from commit e606e56ce7643631c91800354a0dd8ed5ded161d)
2025-08-28 06:38:20 +00:00
Shariq Ansari
5a941e0944 chore: Bosnian translations
(cherry picked from commit a8a75f6e977b150f2c54fd753b957057cabad974)
2025-08-28 06:38:19 +00:00
Shariq Ansari
4987545595 chore: Indonesian translations
(cherry picked from commit 35e07b321ca30d9bc22ccbc299ebcde817bfbb5d)
2025-08-28 06:38:19 +00:00
Shariq Ansari
f53e35117a chore: Portuguese, Brazilian translations
(cherry picked from commit 28ce5762f8071da27f6d5a2ce4e5f865e22e7922)
2025-08-28 06:38:19 +00:00
Shariq Ansari
de2939d863 chore: Swedish translations
(cherry picked from commit 97367afed113e2a96b73a6258f916cfc4e90a9b7)
2025-08-28 06:38:19 +00:00
Shariq Ansari
25a26d3e2c chore: Serbian (Cyrillic) translations
(cherry picked from commit d1b229c4590f004226e5499e4b66a90835398609)
2025-08-28 06:38:18 +00:00
Shariq Ansari
efd02c3459 chore: Polish translations
(cherry picked from commit 335f73a0e6fb84d222498848d245ae3e6f30a915)
2025-08-28 06:38:18 +00:00
Shariq Ansari
13e72bf7f3 chore: Italian translations
(cherry picked from commit ef38c4a882634e104b14054f954ad60b15f7fbe2)
2025-08-28 06:38:18 +00:00
Frappe PR Bot
7b8cc6caa3 chore(release): Bumped to Version 1.52.9 2025-08-26 07:03:49 +00:00
Shariq Ansari
d1e66cd5bb
Merge pull request #1187 from frappe/main-hotfix 2025-08-26 12:32:46 +05:30
Shariq Ansari
3a9bad7954
Merge pull request #1188 from frappe/mergify/bp/main-hotfix/pr-1182
fix: do not allow saving public view kanban changes for non managers (backport #1182)
2025-08-26 12:27:47 +05:30
Shariq Ansari
3f6e69c3f6
Merge pull request #1186 from frappe/mergify/bp/main-hotfix/pr-1185
fix: remove "read only" flag for primary email, mobile & phone no (backport #1185)
2025-08-26 12:27:32 +05:30
Shariq Ansari
57fb0e07cf fix: do not allow saving public view kanban changes for non managers
(cherry picked from commit 4301cd48061ab853eb975e7d47e2e6c39856f46a)
2025-08-26 06:56:49 +00:00
Shariq Ansari
4cfab1fbb6
Merge pull request #1183 from frappe/mergify/bp/main-hotfix/pr-1178 2025-08-26 12:25:46 +05:30
Pratik Badhe
c851b9f4b3 fix: remove "read only" flag for primary email, mobile & phone no
(cherry picked from commit 7807c12114b215be3f7471615492b982d2dca94d)
2025-08-26 06:54:45 +00:00
Shariq Ansari
7d8f980c87
Merge pull request #1184 from frappe/mergify/bp/main-hotfix/pr-1179 2025-08-26 12:24:22 +05:30
Shariq Ansari
2ccae25bfe
chore: Fix merge conflict in main.pot 2025-08-26 12:22:46 +05:30
Shariq Ansari
1da242fd37 chore: Indonesian translations
(cherry picked from commit 5ab41a5ebb6f1d9e14650dd1b7c61fcdc4e0ccd0)
2025-08-26 06:42:50 +00:00
Shariq Ansari
35b7e69426 chore: Italian translations
(cherry picked from commit e7c09b6f2ffe46e65299e40178f651bb07fe09cb)
2025-08-26 06:42:49 +00:00
frappe-pr-bot
fbaca7f154 chore: update POT file
(cherry picked from commit bf63bd54df26ff9d4e17a6ce321059742cc6d2bd)

# Conflicts:
#	crm/locale/main.pot
2025-08-26 06:42:37 +00:00
Shariq Ansari
913094dce3
Merge pull request #1174 from frappe/mergify/bp/main-hotfix/pr-1173
fix: reorder idx if grid row is reordered (backport #1173)
2025-08-21 11:35:05 +05:30
Shariq Ansari
4d619a908c fix: update button state to use document properties
(cherry picked from commit 41118eda97b9aeaa47814c2c499dc8e4c6f57b47)
2025-08-21 06:03:21 +00:00
Shariq Ansari
6dc8975c08 fix: reorder idx if grid row is reordered
(cherry picked from commit cd96171a4c1a784ffa2b00d28e2b22921b9c9f37)
2025-08-21 06:03:20 +00:00
Shariq Ansari
1b0a92c0c5
Merge pull request #1172 from frappe/mergify/bp/main-hotfix/pr-1133
fix(Org Modal): Setting loading false in case of Validation Error (backport #1133)
2025-08-20 14:35:43 +05:30
wasim3357
bd3aca85ac fix(Org Modal): Setting loading false in case of Validation Error
In this case user can add the details and save the form again instead of refreshing and then trying again for fresh.

(cherry picked from commit ea2e44a2befd5cfd775f7e1b0d3c2321f6d075b0)
2025-08-20 09:05:12 +00:00
Shariq Ansari
6d7372240f
Merge pull request #1171 from frappe/mergify/bp/main-hotfix/pr-1167 2025-08-20 13:33:34 +05:30
Shariq Ansari
c799d1502b chore: Esperanto translations
(cherry picked from commit 8d7a5f22fda1cc62449ae0e9f49967f53964fae6)
2025-08-20 07:51:31 +00:00
Shariq Ansari
acdfe6c82b chore: Croatian translations
(cherry picked from commit a31ff7499934e03b4a1c98e884762fd0735f4cdc)
2025-08-20 07:51:31 +00:00
Shariq Ansari
17687690cf chore: Thai translations
(cherry picked from commit c60979f1ab8d7ad8b52fc64e0fff69215681b100)
2025-08-20 07:51:31 +00:00
Shariq Ansari
f28920dd60 chore: Persian translations
(cherry picked from commit b5739efbbc101dddc035581dd08a5ad20830eaa7)
2025-08-20 07:51:30 +00:00
Shariq Ansari
90f61dffa6 chore: Vietnamese translations
(cherry picked from commit 96e014e6cacbf9832a3ee2f2c825007b8abf3330)
2025-08-20 07:51:30 +00:00
Shariq Ansari
556f8e6b11 chore: Chinese Simplified translations
(cherry picked from commit d0020b8a90ecdda28c03a7ffd6d6f6e61ee16bed)
2025-08-20 07:51:30 +00:00
Shariq Ansari
78aea3bbac chore: Turkish translations
(cherry picked from commit f32b86e7e7ef5f1f5ec6ed0a48e6af2cd604d4cc)
2025-08-20 07:51:30 +00:00
Shariq Ansari
67f75289c7 chore: Russian translations
(cherry picked from commit 7cab5d981521524adcaeacc21a081cd6337983ab)
2025-08-20 07:51:29 +00:00
Shariq Ansari
8e86a06858 chore: Portuguese translations
(cherry picked from commit a6a22aa3930ccb1d5b7dbc2c605ef2b7b09ef55e)
2025-08-20 07:51:29 +00:00
Shariq Ansari
445f5d7ade chore: Dutch translations
(cherry picked from commit fd098a0766769b4cb1be8e24f2c02a1a66104cb7)
2025-08-20 07:51:29 +00:00
Shariq Ansari
015228488b chore: Hungarian translations
(cherry picked from commit 36326526d57a78ef2b4bde4db57bf7292e2ea433)
2025-08-20 07:51:28 +00:00
Shariq Ansari
9a0e0ed721 chore: Czech translations
(cherry picked from commit f20a903e784419e152800e42baf56f6924a350bb)
2025-08-20 07:51:28 +00:00
Shariq Ansari
89b392d59b chore: Arabic translations
(cherry picked from commit 0f0564066db24fd764bd678ad20e1259cd32e60a)
2025-08-20 07:51:28 +00:00
Shariq Ansari
799dedb582 chore: Spanish translations
(cherry picked from commit 7b6a4d3b307a5bddd9d619faf8fe16bcba19a01a)
2025-08-20 07:51:27 +00:00
Shariq Ansari
9418df86f9 chore: French translations
(cherry picked from commit 175c45055977811e38305662dde992855483b67a)
2025-08-20 07:51:27 +00:00
Shariq Ansari
57dd748cae chore: German translations
(cherry picked from commit 5b79141dd53efe48b243202348bba0cb84f3c298)
2025-08-20 07:51:27 +00:00
Shariq Ansari
06b4e4d544 chore: Serbian (Latin) translations
(cherry picked from commit 97de6543c20dcdec733becd778dd366ec27b52bc)
2025-08-20 07:51:27 +00:00
Shariq Ansari
e98d54cdd9 chore: Bosnian translations
(cherry picked from commit bc424265e029e45f941df43687ac4c70e2e5ef02)
2025-08-20 07:51:26 +00:00
Shariq Ansari
a00838b7a0 chore: Indonesian translations
(cherry picked from commit 15d057b63c13c8c1312973d41176dca324d0aa31)
2025-08-20 07:51:26 +00:00
Shariq Ansari
fad4bc994d chore: Portuguese, Brazilian translations
(cherry picked from commit 27a121c270d63e42c362e32f8811e9692ffb48de)
2025-08-20 07:51:26 +00:00
Shariq Ansari
b3752d63db chore: Swedish translations
(cherry picked from commit d99a4bc3ff7c45fb6d492e71db4dc7a348bb3ac7)
2025-08-20 07:51:25 +00:00
Shariq Ansari
4c13c5143f chore: Serbian (Cyrillic) translations
(cherry picked from commit d6251adae3f429e332a565d556a919fd0c1e01c1)
2025-08-20 07:51:25 +00:00
Shariq Ansari
9423af5cc1 chore: Polish translations
(cherry picked from commit 388d3e93693d8ee84ce0062bb65e035f2d2e537d)
2025-08-20 07:51:25 +00:00
Shariq Ansari
dcc3b88d4f chore: Italian translations
(cherry picked from commit f8f0800f97853d9710c13d8d8d11d7054ac24c8b)
2025-08-20 07:51:25 +00:00
Shariq Ansari
a55b69a945
Merge pull request #1170 from frappe/mergify/bp/main-hotfix/pr-1169
fix: dropdown item is not updating (backport #1169)
2025-08-20 13:20:05 +05:30
Shariq Ansari
89abee30bf fix: dropdown item is not updating
(cherry picked from commit 8ea94765ce351df2586ab71238ef6baa8068613e)
2025-08-20 07:45:21 +00:00
Frappe PR Bot
066371bd76 chore(release): Bumped to Version 1.52.8 2025-08-19 08:12:22 +00:00
Shariq Ansari
f61a40698d
Merge pull request #1166 from frappe/mergify/bp/main/pr-1164
fix: More fixes (backport #1164)
2025-08-19 13:39:38 +05:30
Shariq Ansari
0b9c0915c7
Merge pull request #1165 from frappe/mergify/bp/main-hotfix/pr-1164
fix: More fixes (backport #1164)
2025-08-19 13:39:35 +05:30
Shariq Ansari
e6781ea4bb fix: remove read-only attribute from TwiML SID field
(cherry picked from commit 247a7c4da63e8aa639383469ad11d433421f4c71)
2025-08-19 08:08:46 +00:00
Shariq Ansari
277fb85e32 fix: remove read-only attribute from TwiML SID field
(cherry picked from commit 247a7c4da63e8aa639383469ad11d433421f4c71)
2025-08-19 08:08:46 +00:00
Shariq Ansari
4592dfcd13 fix: add immediate execution to watch for assignees updates
(cherry picked from commit f2d87fa801b2c906e182f85bf8e7b29f52ccab4a)
2025-08-19 08:08:45 +00:00
Shariq Ansari
cf0f922f2f fix: add immediate execution to watch for assignees updates
(cherry picked from commit f2d87fa801b2c906e182f85bf8e7b29f52ccab4a)
2025-08-19 08:08:45 +00:00
Frappe PR Bot
bc35d6b98f chore(release): Bumped to Version 1.52.7 2025-08-19 06:58:06 +00:00
Shariq Ansari
3fbd40b591
Merge pull request #1163 from frappe/mergify/bp/main/pr-1161
fix: More fixes (backport #1161)
2025-08-19 12:27:16 +05:30
Shariq Ansari
f50b8a78eb
Merge pull request #1162 from frappe/mergify/bp/main-hotfix/pr-1161
fix: More fixes (backport #1161)
2025-08-19 12:27:12 +05:30
Shariq Ansari
5212a61388 fix: update Dropdown styling in SLASection component
(cherry picked from commit edd0ec5f68eac0bfd9005adbbbd95fedd0c8e337)
2025-08-19 06:56:52 +00:00
Shariq Ansari
0d1c057cf3 fix: align action buttons in GridFieldsEditorModal
(cherry picked from commit a76bd2cab2b4dd2a8a9038f6890f3b9294a375a2)
2025-08-19 06:56:52 +00:00
Shariq Ansari
5a243d29da fix: update Dropdown styling in SLASection component
(cherry picked from commit edd0ec5f68eac0bfd9005adbbbd95fedd0c8e337)
2025-08-19 06:56:51 +00:00
Shariq Ansari
992b47e531 fix: convert to deal modals's convert button
(cherry picked from commit 25d9d562e6b150d94ba1b3065945fd0c12f10c43)
2025-08-19 06:56:51 +00:00
Shariq Ansari
ee8f806f64 fix: align action buttons in GridFieldsEditorModal
(cherry picked from commit a76bd2cab2b4dd2a8a9038f6890f3b9294a375a2)
2025-08-19 06:56:51 +00:00
Shariq Ansari
bc0ca74f88 fix: convert to deal modals's convert button
(cherry picked from commit 25d9d562e6b150d94ba1b3065945fd0c12f10c43)
2025-08-19 06:56:50 +00:00
Frappe PR Bot
55dabaf877 chore(release): Bumped to Version 1.52.6 2025-08-19 05:46:20 +00:00
Shariq Ansari
006c7efc06
Merge pull request #1160 from frappe/mergify/bp/main/pr-1158
fix: reject button is rotated (backport #1158)
2025-08-19 11:14:02 +05:30
Shariq Ansari
4c809a9166
Merge pull request #1159 from frappe/mergify/bp/main-hotfix/pr-1158
fix: reject button is rotated (backport #1158)
2025-08-19 11:13:58 +05:30
Shariq Ansari
9e19e54f75 fix: reject button is rotated
(cherry picked from commit afa96c330bb123067b15526c22d46c6e932ace01)
2025-08-19 05:43:30 +00:00
Shariq Ansari
806f75a2fe fix: reject button is rotated
(cherry picked from commit afa96c330bb123067b15526c22d46c6e932ace01)
2025-08-19 05:43:28 +00:00
Frappe PR Bot
295b0f4c2a chore(release): Bumped to Version 1.52.5 2025-08-19 05:19:06 +00:00
Shariq Ansari
7945527fd6
Merge pull request #1157 from frappe/mergify/bp/main/pr-1155
fix: remove unnecessary cache from dashboardItems resource (backport #1155)
2025-08-19 10:48:17 +05:30
Shariq Ansari
696531f392 fix: remove unnecessary cache from dashboardItems resource
(cherry picked from commit c2a1a1b1d2de8a1640e077cc47a377311f5203d8)
2025-08-19 05:18:05 +00:00
Shariq Ansari
c0d43a9b58
Merge pull request #1156 from frappe/mergify/bp/main-hotfix/pr-1155
fix: remove unnecessary cache from dashboardItems resource (backport #1155)
2025-08-19 10:48:03 +05:30
Shariq Ansari
584250c4e5 fix: remove unnecessary cache from dashboardItems resource
(cherry picked from commit c2a1a1b1d2de8a1640e077cc47a377311f5203d8)
2025-08-19 05:17:48 +00:00
Frappe PR Bot
ec467ae126 chore(release): Bumped to Version 1.52.4 2025-08-18 20:56:34 +00:00
Shariq Ansari
579fe78e6f
Merge pull request #1154 from frappe/mergify/bp/main/pr-1152
fix: More fixes (backport #1152)
2025-08-19 02:25:32 +05:30
Shariq Ansari
a246a5e6e4
Merge pull request #1153 from frappe/mergify/bp/main-hotfix/pr-1152
fix: More fixes (backport #1152)
2025-08-19 02:25:27 +05:30
Shariq Ansari
daaf015462 fix: prevent adding a column with undefined value in ColumnSettings
(cherry picked from commit 5f0bb46bf4f3c5c99a4120409d84366cb2b969c8)
2025-08-18 20:50:30 +00:00
Shariq Ansari
edb68fe08b refactor: note/task modal
(cherry picked from commit f4551a92c553a8c26d9bcd36b1ae21d6a69c53d7)
2025-08-18 20:50:29 +00:00
Shariq Ansari
7e736b2892 fix: minor fix
(cherry picked from commit e9c197f46e9a23b8a3e118cf1af22218168f4cb3)
2025-08-18 20:50:29 +00:00
Shariq Ansari
3b18f3a86a fix: grid settings/edit-row button alignment
(cherry picked from commit 3a756630f3699c3f86aa74eff174b9a7e8a21623)
2025-08-18 20:50:29 +00:00
Shariq Ansari
f6cf935c9c refactor: update layout structure for CRM Deal-Data Fields to show products table
(cherry picked from commit a77bfd2acae6e6973d8a9e85c73b0e163a94ea88)
2025-08-18 20:50:28 +00:00
Shariq Ansari
1dfbcd1055 fix: ensure reactive access to document title in Lead component
(cherry picked from commit 1cebc1fed858d3e54bace0e46731e4fd0aff0502)
2025-08-18 20:50:28 +00:00
Shariq Ansari
3326230062 refactor: improve layout and structure of quick filter components
(cherry picked from commit 1a90876500afe5f104f8ff7d263cca942b3506f7)
2025-08-18 20:50:28 +00:00
Shariq Ansari
de4471876f patch: create default loast reasons
(cherry picked from commit c4065b95b8f16d7550ddaff543467fb92e59d17c)
2025-08-18 20:50:28 +00:00
Shariq Ansari
41ce361f04 fix: prevent adding a column with undefined value in ColumnSettings
(cherry picked from commit 5f0bb46bf4f3c5c99a4120409d84366cb2b969c8)
2025-08-18 20:50:26 +00:00
Shariq Ansari
466a2b58ee refactor: note/task modal
(cherry picked from commit f4551a92c553a8c26d9bcd36b1ae21d6a69c53d7)
2025-08-18 20:50:26 +00:00
Shariq Ansari
0e71880463 fix: minor fix
(cherry picked from commit e9c197f46e9a23b8a3e118cf1af22218168f4cb3)
2025-08-18 20:50:25 +00:00
Shariq Ansari
1afbc001b5 fix: grid settings/edit-row button alignment
(cherry picked from commit 3a756630f3699c3f86aa74eff174b9a7e8a21623)
2025-08-18 20:50:25 +00:00
Shariq Ansari
9e3eba8ab2 refactor: update layout structure for CRM Deal-Data Fields to show products table
(cherry picked from commit a77bfd2acae6e6973d8a9e85c73b0e163a94ea88)
2025-08-18 20:50:25 +00:00
Shariq Ansari
32405f3120 fix: ensure reactive access to document title in Lead component
(cherry picked from commit 1cebc1fed858d3e54bace0e46731e4fd0aff0502)
2025-08-18 20:50:24 +00:00
Shariq Ansari
d7735d634d refactor: improve layout and structure of quick filter components
(cherry picked from commit 1a90876500afe5f104f8ff7d263cca942b3506f7)
2025-08-18 20:50:24 +00:00
Shariq Ansari
b97a80249c patch: create default loast reasons
(cherry picked from commit c4065b95b8f16d7550ddaff543467fb92e59d17c)
2025-08-18 20:50:24 +00:00
Frappe PR Bot
9c3ddeaf7d chore(release): Bumped to Version 1.52.3 2025-08-18 17:46:55 +00:00
Shariq Ansari
de14eb3ffb
Merge pull request #1151 from frappe/main-hotfix 2025-08-18 23:15:56 +05:30
Shariq Ansari
74cce77dc5
Merge branch 'main' into main-hotfix 2025-08-18 23:08:12 +05:30
Shariq Ansari
2352f51838
Merge pull request #1149 from frappe/mergify/bp/main-hotfix/pr-1129 2025-08-18 23:03:26 +05:30
Shariq Ansari
0e2be93e92
chore: resolved conflict 2025-08-18 23:02:22 +05:30
Shariq Ansari
903c214c3d
Merge pull request #1150 from frappe/mergify/bp/main-hotfix/pr-1130 2025-08-18 22:56:35 +05:30
Shariq Ansari
9c653cf5e7
chore: resolved conflict 2025-08-18 22:54:01 +05:30
frappe-pr-bot
3c296a67a2 chore: update POT file
(cherry picked from commit 00e3bd12ccfa49e7d97527641924756c521dc808)

# Conflicts:
#	crm/locale/main.pot
2025-08-18 17:22:30 +00:00
Shariq Ansari
9196369c17
Merge pull request #1148 from frappe/mergify/bp/main-hotfix/pr-1142 2025-08-18 22:51:26 +05:30
Shariq Ansari
853ef4859d
Merge pull request #1147 from frappe/mergify/bp/main-hotfix/pr-1145 2025-08-18 22:49:32 +05:30
Shariq Ansari
c861fbda49 chore: Persian translations
(cherry picked from commit d4f99a411cc4a0a7b36866354ba4dbc22238de31)
2025-08-18 17:19:29 +00:00
Shariq Ansari
a81f3685bc chore: Persian translations
(cherry picked from commit 4884ca0bd6cfcb914fb91bc11de2d3494d2a34ea)
2025-08-18 17:19:29 +00:00
Shariq Ansari
73d13351b5 chore: Italian translations
(cherry picked from commit 2a7c9ef9e821d5ffd4743f26ce232bbadd87a169)

# Conflicts:
#	crm/locale/it.po
2025-08-18 17:19:28 +00:00
Shariq Ansari
43e8f2a48f chore: Italian translations
(cherry picked from commit cb3f67f2317d488a2da3ed6df331ad30b95a897e)

# Conflicts:
#	crm/locale/it.po
2025-08-18 17:19:28 +00:00
Shariq Ansari
f347919dbf chore: German translations
(cherry picked from commit d539bc075f97cbc44a96a4efcdb305e81b975db0)
2025-08-18 17:19:28 +00:00
Shariq Ansari
14622a00b3 chore: Italian translations
(cherry picked from commit 818fd6fcdd5586b323de90a075efa82c9251fb6e)

# Conflicts:
#	crm/locale/it.po
2025-08-18 17:19:28 +00:00
frappe-pr-bot
4a83b52ab5 chore: update POT file
(cherry picked from commit 73b2c36bbcedf696e4eff3cf0a83b36ac66a5af7)
2025-08-18 17:19:26 +00:00
Shariq Ansari
30fed5f6ad
Merge pull request #1146 from frappe/mergify/bp/main-hotfix/pr-1143
fixes to incorporate latest frappe-ui version  (backport #1143)
2025-08-18 22:47:46 +05:30
Shariq Ansari
96031d2288 build(deps): bump frappeui to 0.1.189
(cherry picked from commit 1679a67dc6a785db93fbf09ecb4b3ecf7e4e7c8f)
2025-08-18 17:13:23 +00:00
Shariq Ansari
58a0ef2d0e refactor: update tooltip bindings to use translation function and improve dropdown actions
(cherry picked from commit c5a8df19aeafdac60b74cadcf178ee297e9fc9b8)
2025-08-18 17:10:22 +00:00
Shariq Ansari
7b2168232e refactor: replace NestedPopover with Popover component across multiple files
(cherry picked from commit 38b6674cc134a2cffa907c03dbdfce9b7c916e01)
2025-08-18 17:10:22 +00:00
Shariq Ansari
d0dc642b12 refactor: Button components across multiple files to use icon/left-icon/right-icon prop
(cherry picked from commit 672c5eb7333fe4c48055f0acc2d287d545015970)
2025-08-18 17:10:21 +00:00
Shariq Ansari
e4722a79cc fix: show dashboard to all
(cherry picked from commit 948ce994824260b4ca6303f0b729bb1beb760b0c)
2025-08-18 17:10:21 +00:00
Shariq Ansari
671ce54380 fix: lead/deal status dropdown is not renderring
(cherry picked from commit 3791e2ae70067a1be9aba1e472a497e3dff8006a)
2025-08-18 17:10:20 +00:00
Shariq Ansari
d4ac8772ae fix: add toast import to CurrencySettings component
(cherry picked from commit 68d1172b8fee86603586b21271ff5dc3f627734b)
2025-08-18 17:10:20 +00:00
Shariq Ansari
1df71070d0 fix: adjust UserDropdown padding in AppSidebar
(cherry picked from commit c94e61bfcec1f0a12bfe52a4403e0ff6990a77fa)
2025-08-18 17:10:20 +00:00
Shariq Ansari
58d4b7afae fix: doc was not associated with value
(cherry picked from commit 8b557a5963d3651b697c859435a46f639510416b)
2025-08-18 17:10:20 +00:00
Shariq Ansari
9e08b68f22
Merge pull request #1127 from frappe/mergify/bp/main/pr-1126 2025-08-08 17:14:39 +05:30
Shariq Ansari
3a38ccace0 chore: Italian translations
(cherry picked from commit 840eb664ce09dc137f39c26053fcc4572f36cba7)
2025-08-08 11:30:19 +00:00
154 changed files with 55915 additions and 22338 deletions

1
.gitignore vendored
View File

@ -7,6 +7,5 @@ dev-dist
tags
node_modules
crm/public/frontend
frontend/yarn.lock
crm/www/crm.html
build

View File

@ -1,4 +1,4 @@
__version__ = "1.52.2"
__version__ = "1.53.1"
__title__ = "Frappe CRM"

View File

@ -0,0 +1,32 @@
import frappe
@frappe.whitelist()
def get_assignment_rules_list():
assignment_rules = []
for docname in frappe.get_all(
"Assignment Rule", filters={"document_type": ["in", ["CRM Lead", "CRM Deal"]]}
):
doc = frappe.get_value(
"Assignment Rule",
docname,
fieldname=[
"name",
"description",
"disabled",
"priority",
],
as_dict=True,
)
users_exists = bool(frappe.db.exists("Assignment Rule User", {"parent": docname.name}))
assignment_rules.append({**doc, "users_exists": users_exists})
return assignment_rules
@frappe.whitelist()
def duplicate_assignment_rule(docname, new_name):
doc = frappe.get_doc("Assignment Rule", docname)
doc.name = new_name
doc.assignment_rule_name = new_name
doc.insert()
return doc

View File

@ -750,7 +750,11 @@ def getCounts(d, doctype):
@frappe.whitelist()
def get_linked_docs_of_document(doctype, docname):
doc = frappe.get_doc(doctype, docname)
try:
doc = frappe.get_doc(doctype, docname)
except frappe.DoesNotExistError:
return []
linked_docs = get_linked_docs(doc)
dynamic_linked_docs = get_dynamic_linked_docs(doc)
@ -759,7 +763,14 @@ def get_linked_docs_of_document(doctype, docname):
docs_data = []
for doc in linked_docs:
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
if not doc.get("reference_doctype") or not doc.get("reference_docname"):
continue
try:
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
except (frappe.DoesNotExistError, frappe.ValidationError):
continue
title = data.get("title")
if data.doctype == "CRM Call Log":
title = f"Call from {data.get('from')} to {data.get('to')}"
@ -767,6 +778,9 @@ def get_linked_docs_of_document(doctype, docname):
if data.doctype == "CRM Deal":
title = data.get("organization")
if data.doctype == "CRM Notification":
title = data.get("message")
docs_data.append(
{
"doc": data.doctype,
@ -779,25 +793,51 @@ def get_linked_docs_of_document(doctype, docname):
def remove_doc_link(doctype, docname):
linked_doc_data = frappe.get_doc(doctype, docname)
linked_doc_data.update(
{
"reference_doctype": None,
"reference_docname": None,
}
)
linked_doc_data.save(ignore_permissions=True)
if not doctype or not docname:
return
try:
linked_doc_data = frappe.get_doc(doctype, docname)
if doctype == "CRM Notification":
delete_notification_type = {
"notification_type_doctype": "",
"notification_type_doc": "",
}
delete_references = {
"reference_doctype": "",
"reference_name": "",
}
if linked_doc_data.get("notification_type_doctype") == linked_doc_data.get("reference_doctype"):
delete_references.update(delete_notification_type)
linked_doc_data.update(delete_references)
else:
linked_doc_data.update(
{
"reference_doctype": "",
"reference_docname": "",
}
)
linked_doc_data.save(ignore_permissions=True)
except (frappe.DoesNotExistError, frappe.ValidationError):
pass
def remove_contact_link(doctype, docname):
linked_doc_data = frappe.get_doc(doctype, docname)
linked_doc_data.update(
{
"contact": None,
"contacts": [],
}
)
linked_doc_data.save(ignore_permissions=True)
if not doctype or not docname:
return
try:
linked_doc_data = frappe.get_doc(doctype, docname)
linked_doc_data.update(
{
"contact": None,
"contacts": [],
}
)
linked_doc_data.save(ignore_permissions=True)
except (frappe.DoesNotExistError, frappe.ValidationError):
pass
@frappe.whitelist()
@ -806,13 +846,19 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
items = frappe.parse_json(items)
for item in items:
if remove_contact:
remove_contact_link(item["doctype"], item["docname"])
else:
remove_doc_link(item["doctype"], item["docname"])
if not item.get("doctype") or not item.get("docname"):
continue
if delete:
frappe.delete_doc(item["doctype"], item["docname"])
try:
if remove_contact:
remove_contact_link(item["doctype"], item["docname"])
else:
remove_doc_link(item["doctype"], item["docname"])
if delete:
frappe.delete_doc(item["doctype"], item["docname"])
except (frappe.DoesNotExistError, frappe.ValidationError):
# Skip if document doesn't exist or has validation errors
continue
return "success"
@ -821,19 +867,40 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
def delete_bulk_docs(doctype, items, delete_linked=False):
from frappe.desk.reportview import delete_bulk
if not doctype:
frappe.throw("Doctype is required")
if not items:
frappe.throw("Items are required")
items = frappe.parse_json(items)
if not isinstance(items, list):
frappe.throw("Items must be a list")
for doc in items:
linked_docs = get_linked_docs_of_document(doctype, doc)
for linked_doc in linked_docs:
remove_linked_doc_reference(
[
{
"doctype": linked_doc["reference_doctype"],
"docname": linked_doc["reference_docname"],
}
],
remove_contact=doctype == "Contact",
delete=delete_linked,
try:
if not frappe.db.exists(doctype, doc):
frappe.log_error(f"Document {doctype} {doc} does not exist", "Bulk Delete Error")
continue
linked_docs = get_linked_docs_of_document(doctype, doc)
for linked_doc in linked_docs:
if not linked_doc.get("reference_doctype") or not linked_doc.get("reference_docname"):
continue
remove_linked_doc_reference(
[
{
"doctype": linked_doc["reference_doctype"],
"docname": linked_doc["reference_docname"],
}
],
remove_contact=doctype == "Contact",
delete=delete_linked,
)
except Exception as e:
frappe.log_error(
f"Error processing linked docs for {doctype} {doc}: {str(e)}", "Bulk Delete Error"
)
if len(items) > 10:

View File

@ -10,8 +10,15 @@ from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
def validate(doc, method):
if doc.type == "Incoming" and doc.get("from"):
name, doctype = get_lead_or_deal_from_number(doc.get("from"))
doc.reference_doctype = doctype
doc.reference_name = name
if name != None:
doc.reference_doctype = doctype
doc.reference_name = name
if doc.type == "Outgoing" and doc.get("to"):
name, doctype = get_lead_or_deal_from_number(doc.get("to"))
if name != None:
doc.reference_doctype = doctype
doc.reference_name = name
def on_update(doc, method):
@ -29,7 +36,7 @@ def on_update(doc, method):
def notify_agent(doc):
if doc.type == "Incoming":
doctype = doc.reference_doctype
if doctype.startswith("CRM "):
if doctype and doctype.startswith("CRM "):
doctype = doctype[4:].lower()
notification_text = f"""
<div class="mb-2 leading-5 text-ink-gray-5">

View File

@ -26,8 +26,9 @@ def create_default_manager_dashboard(force=False):
doc.title = "Manager Dashboard"
doc.layout = default_manager_dashboard_layout()
doc.insert(ignore_permissions=True)
elif force:
else:
doc = frappe.get_doc("CRM Dashboard", "Manager Dashboard")
doc.layout = default_manager_dashboard_layout()
doc.save(ignore_permissions=True)
if force:
doc.layout = default_manager_dashboard_layout()
doc.save(ignore_permissions=True)
return doc.layout

View File

@ -129,15 +129,13 @@
"fieldname": "email",
"fieldtype": "Data",
"label": "Primary Email",
"options": "Email",
"read_only": 1
"options": "Email"
},
{
"fieldname": "mobile_no",
"fieldtype": "Data",
"label": "Primary Mobile No",
"options": "Phone",
"read_only": 1
"options": "Phone"
},
{
"default": "Qualification",
@ -251,8 +249,7 @@
"fieldname": "phone",
"fieldtype": "Data",
"label": "Primary Phone",
"options": "Phone",
"read_only": 1
"options": "Phone"
},
{
"fieldname": "log_tab",
@ -435,7 +432,7 @@
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-07-13 11:54:20.608489",
"modified": "2025-08-26 12:12:56.324245",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Deal",

View File

@ -25,7 +25,7 @@ class CRMDeal(Document):
add_status_change_log(self)
if frappe.db.get_value("CRM Deal Status", self.status, "type") == "Won":
self.closed_date = frappe.utils.nowdate()
self.validate_forcasting_fields()
self.validate_forecasting_fields()
self.validate_lost_reason()
self.update_exchange_rate()
@ -151,9 +151,21 @@ class CRMDeal(Document):
if not self.probability or self.probability == 0:
self.probability = frappe.db.get_value("CRM Deal Status", self.status, "probability") or 0
def validate_forcasting_fields(self):
def update_expected_deal_value(self):
"""
Update the expected deal value based on the net total or total.
"""
if (
frappe.db.get_single_value("FCRM Settings", "auto_update_expected_deal_value")
and (self.net_total or self.total)
and self.expected_deal_value
):
self.expected_deal_value = self.net_total or self.total
def validate_forecasting_fields(self):
self.update_closed_date()
self.update_default_probability()
self.update_expected_deal_value()
if frappe.db.get_single_value("FCRM Settings", "enable_forecasting"):
if not self.expected_deal_value or self.expected_deal_value == 0:
frappe.throw(_("Expected Deal Value is required."), frappe.MandatoryError)

View File

@ -63,8 +63,7 @@
"fieldname": "twiml_sid",
"fieldtype": "Data",
"label": "TwiML SID",
"permlevel": 1,
"read_only": 1
"permlevel": 1
},
{
"fieldname": "section_break_ssqj",
@ -105,7 +104,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-01-15 19:35:13.406254",
"modified": "2025-08-19 13:36:19.823197",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Twilio Settings",
@ -152,8 +151,9 @@
"write": 1
}
],
"row_format": "Dynamic",
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@ -8,6 +8,7 @@
"defaults_tab",
"restore_defaults",
"enable_forecasting",
"auto_update_expected_deal_value",
"currency_tab",
"currency",
"exchange_rate_provider_section",
@ -105,12 +106,19 @@
{
"fieldname": "column_break_vqck",
"fieldtype": "Column Break"
},
{
"default": "1",
"description": "Automatically update \"Expected Deal Value\" based on the total value of associated products in a deal",
"fieldname": "auto_update_expected_deal_value",
"fieldtype": "Check",
"label": "Auto Update Expected Deal Value"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-07-29 11:26:50.420614",
"modified": "2025-09-16 17:33:26.406549",
"modified_by": "Administrator",
"module": "FCRM",
"name": "FCRM Settings",

View File

@ -25,6 +25,8 @@ def after_install(force=False):
add_standard_dropdown_items()
add_default_scripts()
create_default_manager_dashboard(force)
create_assignment_rule_custom_fields()
add_assignment_rule_property_setters()
frappe.db.commit()
@ -192,7 +194,7 @@ def add_default_fields_layout(force=False):
},
"CRM Deal-Data Fields": {
"doctype": "CRM Deal",
"layout": '[{"label": "Details", "name": "details_section", "opened": true, "columns": [{"name": "column_z9XL", "fields": ["organization", "annual_revenue", "next_step"]}, {"name": "column_gM4w", "fields": ["website", "close_date", "deal_owner"]}, {"name": "column_gWmE", "fields": ["territory", "probability"]}]}]',
"layout": '[{"name":"first_tab","sections":[{"label":"Details","name":"details_section","opened":true,"columns":[{"name":"column_z9XL","fields":["organization","annual_revenue","next_step"]},{"name":"column_gM4w","fields":["website","closed_date","deal_owner"]},{"name":"column_gWmE","fields":["territory","probability"]}]},{"label":"Products","name":"section_jHhQ","opened":true,"columns":[{"name":"column_xiNF","fields":["products"]}],"editingLabel":false,"hideLabel":true},{"label":"New Section","name":"section_WNOQ","opened":true,"columns":[{"name":"column_ziBW","fields":["total"]},{"label":"","name":"column_wuwA","fields":["net_total"]}],"hideBorder":true,"hideLabel":true}]}]',
},
}
@ -421,3 +423,80 @@ def add_default_scripts():
for doctype in ["CRM Lead", "CRM Deal"]:
create_product_details_script(doctype)
create_forecasting_script()
def add_assignment_rule_property_setters():
"""Add a property setter to the Assignment Rule DocType for assign_condition and unassign_condition."""
default_fields = {
"doctype": "Property Setter",
"doctype_or_field": "DocField",
"doc_type": "Assignment Rule",
"property_type": "Data",
"is_system_generated": 1,
}
if not frappe.db.exists("Property Setter", {"name": "Assignment Rule-assign_condition-depends_on"}):
frappe.get_doc(
{
**default_fields,
"name": "Assignment Rule-assign_condition-depends_on",
"field_name": "assign_condition",
"property": "depends_on",
"value": "eval: !doc.assign_condition_json",
}
).insert()
else:
frappe.db.set_value(
"Property Setter",
{"name": "Assignment Rule-assign_condition-depends_on"},
"value",
"eval: !doc.assign_condition_json",
)
if not frappe.db.exists("Property Setter", {"name": "Assignment Rule-unassign_condition-depends_on"}):
frappe.get_doc(
{
**default_fields,
"name": "Assignment Rule-unassign_condition-depends_on",
"field_name": "unassign_condition",
"property": "depends_on",
"value": "eval: !doc.unassign_condition_json",
}
).insert()
else:
frappe.db.set_value(
"Property Setter",
{"name": "Assignment Rule-unassign_condition-depends_on"},
"value",
"eval: !doc.unassign_condition_json",
)
def create_assignment_rule_custom_fields():
if not frappe.get_meta("Assignment Rule").has_field("assign_condition_json"):
click.secho("* Installing Custom Fields in Assignment Rule")
create_custom_fields(
{
"Assignment Rule": [
{
"description": "Autogenerated field by CRM App",
"fieldname": "assign_condition_json",
"fieldtype": "Code",
"label": "Assign Condition JSON",
"insert_after": "assign_condition",
"depends_on": "eval: doc.assign_condition_json",
},
{
"description": "Autogenerated field by CRM App",
"fieldname": "unassign_condition_json",
"fieldtype": "Code",
"label": "Unassign Condition JSON",
"insert_after": "unassign_condition",
"depends_on": "eval: doc.unassign_condition_json",
},
],
}
)
frappe.clear_cache(doctype="Assignment Rule")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6392
crm/locale/da.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6392
crm/locale/nb.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,4 +14,6 @@ crm.patches.v1_0.update_layouts_to_new_format
crm.patches.v1_0.move_twilio_agent_to_telephony_agent
crm.patches.v1_0.create_default_scripts # 13-06-2025
crm.patches.v1_0.update_deal_status_probabilities
crm.patches.v1_0.update_deal_status_type
crm.patches.v1_0.update_deal_status_type
crm.patches.v1_0.create_default_lost_reasons
crm.patches.v1_0.add_fields_in_assignment_rule

View File

@ -0,0 +1,9 @@
from crm.install import (
add_assignment_rule_property_setters,
create_assignment_rule_custom_fields,
)
def execute():
create_assignment_rule_custom_fields()
add_assignment_rule_property_setters()

View File

@ -0,0 +1,5 @@
from crm.install import add_default_lost_reasons
def execute():
add_default_lost_reasons()

@ -1 +1 @@
Subproject commit b295b54aaa3a2a22f455df819d87433dc6b9ff6a
Subproject commit c9a0fc937cc897864857271b3708a0c675379015

3
frontend/.gitignore vendored
View File

@ -2,4 +2,5 @@ node_modules
.DS_Store
dist
dist-ssr
*.local
*.local
components.d.ts

View File

@ -33,7 +33,7 @@ declare module 'vue' {
Autocomplete: typeof import('./src/components/frappe-ui/Autocomplete.vue')['default']
AvatarIcon: typeof import('./src/components/Icons/AvatarIcon.vue')['default']
BrandLogo: typeof import('./src/components/BrandLogo.vue')['default']
BrandSettings: typeof import('./src/components/Settings/General/BrandSettings.vue')['default']
BrandSettings: typeof import('./src/components/Settings/BrandSettings.vue')['default']
BulkDeleteLinkedDocModal: typeof import('./src/components/BulkDeleteLinkedDocModal.vue')['default']
CalendarIcon: typeof import('./src/components/Icons/CalendarIcon.vue')['default']
CallArea: typeof import('./src/components/Activities/CallArea.vue')['default']
@ -63,7 +63,7 @@ declare module 'vue' {
CountUpTimer: typeof import('./src/components/CountUpTimer.vue')['default']
CreateDocumentModal: typeof import('./src/components/Modals/CreateDocumentModal.vue')['default']
CRMLogo: typeof import('./src/components/Icons/CRMLogo.vue')['default']
CurrencySettings: typeof import('./src/components/Settings/General/CurrencySettings.vue')['default']
CurrencySettings: typeof import('./src/components/Settings/CurrencySettings.vue')['default']
CustomActions: typeof import('./src/components/CustomActions.vue')['default']
DashboardGrid: typeof import('./src/components/Dashboard/DashboardGrid.vue')['default']
DashboardIcon: typeof import('./src/components/Icons/DashboardIcon.vue')['default']
@ -85,7 +85,6 @@ declare module 'vue' {
DragIcon: typeof import('./src/components/Icons/DragIcon.vue')['default']
DragVerticalIcon: typeof import('./src/components/Icons/DragVerticalIcon.vue')['default']
Dropdown: typeof import('./src/components/frappe-ui/Dropdown.vue')['default']
DropdownItem: typeof import('./src/components/DropdownItem.vue')['default']
DuplicateIcon: typeof import('./src/components/Icons/DuplicateIcon.vue')['default']
DurationIcon: typeof import('./src/components/Icons/DurationIcon.vue')['default']
EditEmailTemplate: typeof import('./src/components/Settings/EmailTemplate/EditEmailTemplate.vue')['default']
@ -128,11 +127,10 @@ declare module 'vue' {
FileVideoIcon: typeof import('./src/components/Icons/FileVideoIcon.vue')['default']
Filter: typeof import('./src/components/Filter.vue')['default']
FilterIcon: typeof import('./src/components/Icons/FilterIcon.vue')['default']
ForecastingSettings: typeof import('./src/components/Settings/ForecastingSettings.vue')['default']
FormattedInput: typeof import('./src/components/Controls/FormattedInput.vue')['default']
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
GenderIcon: typeof import('./src/components/Icons/GenderIcon.vue')['default']
GeneralSettings: typeof import('./src/components/Settings/General/GeneralSettings.vue')['default']
GeneralSettingsPage: typeof import('./src/components/Settings/General/GeneralSettingsPage.vue')['default']
GlobalModals: typeof import('./src/components/Modals/GlobalModals.vue')['default']
GoogleIcon: typeof import('./src/components/Icons/GoogleIcon.vue')['default']
Grid: typeof import('./src/components/Controls/Grid.vue')['default']
@ -143,7 +141,7 @@ declare module 'vue' {
GroupByIcon: typeof import('./src/components/Icons/GroupByIcon.vue')['default']
HeartIcon: typeof import('./src/components/Icons/HeartIcon.vue')['default']
HelpIcon: typeof import('./src/components/Icons/HelpIcon.vue')['default']
HomeActions: typeof import('./src/components/Settings/General/HomeActions.vue')['default']
HomeActions: typeof import('./src/components/Settings/HomeActions.vue')['default']
Icon: typeof import('./src/components/Icon.vue')['default']
IconPicker: typeof import('./src/components/IconPicker.vue')['default']
ImageUploader: typeof import('./src/components/Controls/ImageUploader.vue')['default']
@ -170,10 +168,6 @@ declare module 'vue' {
LoadingIndicator: typeof import('./src/components/Icons/LoadingIndicator.vue')['default']
LostReasonModal: typeof import('./src/components/Modals/LostReasonModal.vue')['default']
LucideCalendar: typeof import('~icons/lucide/calendar')['default']
LucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
LucidePenLine: typeof import('~icons/lucide/pen-line')['default']
LucideRefreshCcw: typeof import('~icons/lucide/refresh-ccw')['default']
LucideX: typeof import('~icons/lucide/x')['default']
MarkAsDoneIcon: typeof import('./src/components/Icons/MarkAsDoneIcon.vue')['default']
MaximizeIcon: typeof import('./src/components/Icons/MaximizeIcon.vue')['default']
MenuIcon: typeof import('./src/components/Icons/MenuIcon.vue')['default']
@ -188,7 +182,6 @@ declare module 'vue' {
MultiSelectEmailInput: typeof import('./src/components/Controls/MultiSelectEmailInput.vue')['default']
MultiSelectUserInput: typeof import('./src/components/Controls/MultiSelectUserInput.vue')['default']
MuteIcon: typeof import('./src/components/Icons/MuteIcon.vue')['default']
NestedPopover: typeof import('./src/components/NestedPopover.vue')['default']
NewEmailTemplate: typeof import('./src/components/Settings/EmailTemplate/NewEmailTemplate.vue')['default']
NoteArea: typeof import('./src/components/Activities/NoteArea.vue')['default']
NoteIcon: typeof import('./src/components/Icons/NoteIcon.vue')['default']
@ -207,6 +200,8 @@ declare module 'vue' {
PlaybackSpeedOption: typeof import('./src/components/Activities/PlaybackSpeedOption.vue')['default']
PlayIcon: typeof import('./src/components/Icons/PlayIcon.vue')['default']
Popover: typeof import('./src/components/frappe-ui/Popover.vue')['default']
PrimaryDropdown: typeof import('./src/components/PrimaryDropdown.vue')['default']
PrimaryDropdownItem: typeof import('./src/components/PrimaryDropdownItem.vue')['default']
ProfileSettings: typeof import('./src/components/Settings/ProfileSettings.vue')['default']
QuickEntryModal: typeof import('./src/components/Modals/QuickEntryModal.vue')['default']
QuickFilterField: typeof import('./src/components/QuickFilterField.vue')['default']
@ -233,6 +228,7 @@ declare module 'vue' {
SmileIcon: typeof import('./src/components/Icons/SmileIcon.vue')['default']
SortBy: typeof import('./src/components/SortBy.vue')['default']
SortIcon: typeof import('./src/components/Icons/SortIcon.vue')['default']
SparkleIcon: typeof import('./src/components/Icons/SparkleIcon.vue')['default']
SquareAsterisk: typeof import('./src/components/Icons/SquareAsterisk.vue')['default']
StepsIcon: typeof import('./src/components/Icons/StepsIcon.vue')['default']
SuccessIcon: typeof import('./src/components/Icons/SuccessIcon.vue')['default']

View File

@ -13,7 +13,7 @@
"@tiptap/extension-paragraph": "^2.12.0",
"@twilio/voice-sdk": "^2.10.2",
"@vueuse/integrations": "^10.3.0",
"frappe-ui": "^0.1.171",
"frappe-ui": "^0.1.201",
"gemoji": "^8.1.0",
"lodash": "^4.17.21",
"mime": "^4.0.1",

View File

@ -238,12 +238,9 @@
<Button
class="!size-4"
variant="ghost"
:icon="SelectIcon"
@click="activity.show_others = !activity.show_others"
>
<template #icon>
<SelectIcon />
</template>
</Button>
/>
</div>
<div
v-else

View File

@ -9,23 +9,17 @@
<Button
v-if="title == 'Emails'"
variant="solid"
:label="__('New Email')"
iconLeft="plus"
@click="emailBox.show = true"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New Email') }}</span>
</Button>
/>
<Button
v-else-if="title == 'Comments'"
variant="solid"
:label="__('New Comment')"
iconLeft="plus"
@click="emailBox.showComment = true"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New Comment') }}</span>
</Button>
/>
<MultiActionButton
v-else-if="title == 'Calls'"
variant="solid"
@ -34,59 +28,45 @@
<Button
v-else-if="title == 'Notes'"
variant="solid"
:label="__('New Note')"
iconLeft="plus"
@click="modalRef.showNote()"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New Note') }}</span>
</Button>
/>
<Button
v-else-if="title == 'Tasks'"
variant="solid"
:label="__('New Task')"
iconLeft="plus"
@click="modalRef.showTask()"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New Task') }}</span>
</Button>
/>
<Button
v-else-if="title == 'Attachments'"
variant="solid"
:label="__('Upload Attachment')"
iconLeft="plus"
@click="showFilesUploader = true"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('Upload Attachment') }}</span>
</Button>
/>
<div class="flex gap-2 shrink-0" v-else-if="title == 'WhatsApp'">
<Button
:label="__('Send Template')"
@click="showWhatsappTemplates = true"
/>
<Button variant="solid" @click="whatsappBox.show()">
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New Message') }}</span>
</Button>
<Button
variant="solid"
:label="__('New Message')"
iconLeft="plus"
@click="whatsappBox.show()"
/>
</div>
<Dropdown v-else :options="defaultActions" @click.stop>
<template v-slot="{ open }">
<Button variant="solid" class="flex items-center gap-1">
<template #prefix>
<FeatherIcon name="plus" class="h-4 w-4" />
</template>
<span>{{ __('New') }}</span>
<template #suffix>
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
class="h-4 w-4"
/>
</template>
</Button>
<Button
variant="solid"
class="flex items-center gap-1"
:label="__('New')"
iconLeft="plus"
:iconRight="open ? 'chevron-up' : 'chevron-down'"
/>
</template>
</Dropdown>
</div>

View File

@ -38,42 +38,31 @@
</div>
</Tooltip>
<div class="flex gap-1">
<Tooltip
:text="
<Button
:tooltip="
attachment.is_private ? __('Make public') : __('Make private')
"
class="!size-5"
@click.stop="
togglePrivate(attachment.name, attachment.is_private)
"
>
<div>
<Button
class="!size-5"
@click.stop="
togglePrivate(attachment.name, attachment.is_private)
"
>
<template #icon>
<FeatherIcon
:name="attachment.is_private ? 'lock' : 'unlock'"
class="size-3 text-ink-gray-7"
/>
</template>
</Button>
</div>
</Tooltip>
<Tooltip :text="__('Delete attachment')">
<div>
<Button
class="!size-5"
@click.stop="() => deleteAttachment(attachment.name)"
>
<template #icon>
<FeatherIcon
name="trash-2"
class="size-3 text-ink-gray-7"
/>
</template>
</Button>
</div>
</Tooltip>
<template #icon>
<FeatherIcon
:name="attachment.is_private ? 'lock' : 'unlock'"
class="size-3 text-ink-gray-7"
/>
</template>
</Button>
<Button
:tooltip="__('Delete attachment')"
class="!size-5"
@click.stop="() => deleteAttachment(attachment.name)"
>
<template #icon>
<FeatherIcon name="trash-2" class="size-3 text-ink-gray-7" />
</template>
</Button>
</div>
</div>
</div>

View File

@ -1,12 +1,12 @@
<template>
<div class="w-full text-sm text-ink-gray-5">
<div class="flex items-center gap-2">
<Button variant="ghost" @click="playPause">
<template #icon>
<PlayIcon v-if="isPaused" class="size-4 text-ink-gray-5" />
<PauseIcon v-else class="size-4 text-ink-gray-5" />
</template>
</Button>
<Button
variant="ghost"
class="text-ink-gray-5"
:icon="isPaused ? PlayIcon : PauseIcon"
@click="playPause"
/>
<div class="flex gap-2 items-center justify-between flex-1">
<input
class="w-full slider !h-[0.5] bg-surface-gray-3 [&::-webkit-slider-thumb]:shadow [&::-webkit-slider-thumb:hover]:outline [&::-webkit-slider-thumb:hover]:outline-[0.5px]"
@ -61,11 +61,11 @@
</Button>
</div>
<Dropdown :options="options">
<Button variant="ghost" @click="showPlaybackSpeed = false">
<template #icon>
<FeatherIcon class="size-4" name="more-horizontal" />
</template>
</Button>
<Button
icon="more-horizontal"
variant="ghost"
@click="showPlaybackSpeed = false"
/>
</Dropdown>
</div>
</div>

View File

@ -14,12 +14,10 @@
<div class="flex gap-1">
<Button
v-if="isManager() && !isMobileView"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="showDataFieldsModal = true"
>
<template #icon>
<EditIcon />
</template>
</Button>
/>
<Button
label="Save"
:disabled="!document.isDirty"

View File

@ -2,7 +2,9 @@
<div
class="cursor-pointer flex flex-col rounded-md shadow bg-surface-cards px-3 py-1.5 text-base transition-all duration-300 ease-in-out"
>
<div class="-mb-0.5 flex items-center justify-between gap-2 truncate text-ink-gray-9">
<div
class="-mb-0.5 flex items-center justify-between gap-2 truncate text-ink-gray-9"
>
<div class="flex items-center gap-2 truncate">
<span>{{ activity.data.sender_full_name }}</span>
<span class="sm:flex hidden text-sm text-ink-gray-5">
@ -28,32 +30,20 @@
</div>
</Tooltip>
<div class="flex gap-0.5">
<Tooltip :text="__('Reply')">
<div>
<Button
variant="ghost"
class="text-ink-gray-7"
@click="reply(activity.data)"
>
<template #icon>
<ReplyIcon />
</template>
</Button>
</div>
</Tooltip>
<Tooltip :text="__('Reply All')">
<div>
<Button
variant="ghost"
class="text-ink-gray-7"
@click="reply(activity.data, true)"
>
<template #icon>
<ReplyAllIcon />
</template>
</Button>
</div>
</Tooltip>
<Button
:tooltip="__('Reply')"
variant="ghost"
class="text-ink-gray-7"
:icon="ReplyIcon"
@click="reply(activity.data)"
/>
<Button
:tooltip="__('Reply All')"
variant="ghost"
:icon="ReplyAllIcon"
class="text-ink-gray-7"
@click="reply(activity.data, true)"
/>
</div>
</div>
</div>

View File

@ -41,13 +41,13 @@
:options="taskStatusOptions(modalRef.updateTaskStatus, task)"
@click.stop
>
<Tooltip :text="__('Change Status')">
<div>
<Button variant="ghosted" class="hover:bg-surface-gray-4">
<TaskStatusIcon :status="task.status" />
</Button>
</div>
</Tooltip>
<Button
:tooltip="__('Change status')"
variant="ghosted"
class="hover:bg-surface-gray-4"
>
<TaskStatusIcon :status="task.status" />
</Button>
</Dropdown>
<Dropdown
:options="[

View File

@ -1,7 +1,7 @@
<template>
<NestedPopover>
<template #target>
<div class="flex items-center">
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<div class="flex items-center" @click="togglePopover">
<component
v-if="assignees?.length"
:is="assignees?.length == 1 ? 'Button' : 'div'"
@ -11,24 +11,23 @@
<Button v-else :label="__('Assign to')" />
</div>
</template>
<template #body="{ open }">
<template #body="{ isOpen }">
<AssignToBody
v-show="open"
v-show="isOpen"
v-model="assignees"
:docname="docname"
:doctype="doctype"
:open="open"
:open="isOpen"
:onUpdate="ownerField && saveAssignees"
/>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
import NestedPopover from '@/components/NestedPopover.vue'
import MultipleAvatar from '@/components/MultipleAvatar.vue'
import AssignToBody from '@/components/AssignToBody.vue'
import { useDocument } from '@/data/document'
import { toast } from 'frappe-ui'
import { toast, Popover } from 'frappe-ui'
import { computed } from 'vue'
const props = defineProps({

View File

@ -25,23 +25,21 @@
:key="assignee.name"
@click.stop
>
<div>
<div
class="flex items-center text-sm p-0.5 text-ink-gray-6 border border-outline-gray-1 bg-surface-modal rounded-full cursor-pointer"
@click.stop
<div
class="flex items-center text-sm p-0.5 text-ink-gray-6 border border-outline-gray-1 bg-surface-modal rounded-full cursor-pointer"
@click.stop
>
<UserAvatar :user="assignee.name" size="sm" />
<div class="ml-1">{{ getUser(assignee.name).full_name }}</div>
<Button
variant="ghost"
class="rounded-full !size-4 m-1"
@click.stop="removeValue(assignee.name)"
>
<UserAvatar :user="assignee.name" size="sm" />
<div class="ml-1">{{ getUser(assignee.name).full_name }}</div>
<Button
variant="ghost"
class="rounded-full !size-4 m-1"
@click.stop="removeValue(assignee.name)"
>
<template #icon>
<FeatherIcon name="x" class="h-3 w-3 text-ink-gray-6" />
</template>
</Button>
</div>
<template #icon>
<FeatherIcon name="x" class="h-3 w-3 text-ink-gray-6" />
</template>
</Button>
</div>
</Tooltip>
</div>
@ -74,7 +72,7 @@ import UserAvatar from '@/components/UserAvatar.vue'
import Link from '@/components/Controls/Link.vue'
import { usersStore } from '@/stores/users'
import { capture } from '@/telemetry'
import { Tooltip, Switch, toast, createResource } from 'frappe-ui'
import { Tooltip, Switch, createResource } from 'frappe-ui'
import { ref, watch } from 'vue'
const props = defineProps({
@ -154,6 +152,7 @@ watch(
updateAssignees()
}
},
{ immediate: true },
)
async function updateAssignees() {

View File

@ -5,11 +5,9 @@
:label="label"
theme="gray"
variant="outline"
:iconLeft="getIcon()"
@click="toggleDialog()"
>
<template #prefix>
<component :is="getIcon()" class="h-4 w-4" />
</template>
<template #suffix>
<slot name="suffix" />
</template>

View File

@ -13,7 +13,7 @@
</div>
</div>
<div>
<div class="text-ink-gray-5">
<div class="text-ink-gray-5 text-base">
{{
__('Are you sure you want to delete {0} items?', [
props.items?.length,
@ -53,7 +53,7 @@
</div>
</div>
<div>
<div class="text-ink-gray-5">
<div class="text-ink-gray-5 text-base">
{{
confirmDeleteInfo.delete
? __(

View File

@ -1,7 +1,7 @@
<template>
<NestedPopover>
<template #target>
<Button :label="__('Columns')">
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<Button :label="__('Columns')" @click="togglePopover">
<template v-if="hideLabel">
<ColumnsIcon class="h-4" />
</template>
@ -65,37 +65,28 @@
<Button
class="w-full !justify-start !text-ink-gray-5"
variant="ghost"
@click="togglePopover()"
:label="__('Add Column')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover"
/>
</template>
</Autocomplete>
<Button
v-if="columnsUpdated"
class="w-full !justify-start !text-ink-gray-5"
variant="ghost"
@click="reset(close)"
:label="__('Reset Changes')"
>
<template #prefix>
<ReloadIcon class="h-4" />
</template>
</Button>
:iconLeft="ReloadIcon"
@click="reset(close)"
/>
<Button
v-if="!is_default"
class="w-full !justify-start !text-ink-gray-5"
variant="ghost"
@click="resetToDefault(close)"
:label="__('Reset to Default')"
>
<template #prefix>
<ReloadIcon class="h-4" />
</template>
</Button>
:iconLeft="ReloadIcon"
@click="resetToDefault(close)"
/>
</div>
</div>
<div v-else>
@ -144,7 +135,7 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
@ -152,9 +143,9 @@ import ColumnsIcon from '@/components/Icons/ColumnsIcon.vue'
import EditIcon from '@/components/Icons/EditIcon.vue'
import DragIcon from '@/components/Icons/DragIcon.vue'
import ReloadIcon from '@/components/Icons/ReloadIcon.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import { isTouchScreenDevice } from '@/utils'
import { Popover } from 'frappe-ui'
import Draggable from 'vuedraggable'
import { computed, ref } from 'vue'
import { watchOnce } from '@vueuse/core'
@ -219,6 +210,7 @@ const fields = computed(() => {
})
function addColumn(c) {
if (!c) return
let align = ['Float', 'Int', 'Percent', 'Currency'].includes(c.type)
? 'right'
: 'left'

View File

@ -45,11 +45,12 @@
v-slot="{ togglePopover }"
@update:modelValue="() => appendEmoji()"
>
<Button variant="ghost" @click="togglePopover()">
<template #icon>
<SmileIcon class="h-4" />
</template>
</Button>
<Button
:tooltip="__('Insert Emoji')"
:icon="SmileIcon"
variant="ghost"
@click="togglePopover()"
/>
</IconPicker>
<FileUploader
:upload-args="{
@ -61,14 +62,11 @@
>
<template #default="{ openFileSelector }">
<Button
theme="gray"
:tooltip="__('Attach a file')"
variant="ghost"
:icon="AttachmentIcon"
@click="openFileSelector()"
>
<template #icon>
<AttachmentIcon class="h-4" />
</template>
</Button>
/>
</template>
</FileUploader>
</div>

View File

@ -8,24 +8,18 @@
showEmailBox ? '!bg-surface-gray-4 hover:!bg-surface-gray-3' : '',
]"
:label="__('Reply')"
:iconLeft="Email2Icon"
@click="toggleEmailBox()"
>
<template #prefix>
<Email2Icon class="h-4" />
</template>
</Button>
/>
<Button
variant="ghost"
:label="__('Comment')"
:class="[
showCommentBox ? '!bg-surface-gray-4 hover:!bg-surface-gray-3' : '',
]"
:iconLeft="CommentIcon"
@click="toggleCommentBox()"
>
<template #prefix>
<CommentIcon class="h-4" />
</template>
</Button>
/>
</div>
</div>
<div

View File

@ -0,0 +1,454 @@
<template>
<div
class="flex gap-2"
:class="[
{
'items-center': !props.isGroup,
},
]"
>
<div
class="flex gap-2 w-full"
:class="[
{
'items-center justify-between': !props.isGroup,
},
]"
>
<div :class="'text-end text-base text-gray-600'">
<div v-if="props.itemIndex == 0" class="min-w-[66px] text-start">
{{ __('Where') }}
</div>
<div v-else class="min-w-[66px] flex items-start">
<Button
variant="subtle"
class="w-max"
@click="toggleConjunction"
icon-right="refresh-cw"
:disabled="props.itemIndex > 2"
:label="conjunction"
/>
</div>
</div>
<div v-if="!props.isGroup" class="flex items-center gap-2 w-full">
<div id="fieldname" class="w-full">
<Autocomplete
:options="filterableFields.data"
v-model="props.condition[0]"
:placeholder="__('Field')"
@update:modelValue="updateField"
/>
</div>
<div id="operator">
<FormControl
v-if="!props.condition[0]"
disabled
type="text"
:placeholder="__('operator')"
class="w-[100px]"
/>
<FormControl
v-else
:disabled="!props.condition[0]"
type="select"
v-model="props.condition[1]"
@change="updateOperator"
:options="getOperators()"
class="w-max min-w-[100px]"
/>
</div>
<div id="value" class="w-full">
<FormControl
v-if="!props.condition[0]"
disabled
type="text"
:placeholder="__('condition')"
class="w-full"
/>
<component
v-else
:is="getValueControl()"
v-model="props.condition[2]"
@change="updateValue"
:placeholder="__('condition')"
/>
</div>
</div>
<CFConditions
v-if="props.isGroup && !(props.level == 2 || props.level == 4)"
:conditions="props.condition"
:isChild="true"
:level="props.level"
:disableAddCondition="props.disableAddCondition"
/>
<Button
variant="outline"
v-if="props.isGroup && (props.level == 2 || props.level == 4)"
@click="show = true"
:label="__('Open nested conditions')"
/>
</div>
<div :class="'w-max'">
<Dropdown placement="right" :options="dropdownOptions">
<Button variant="ghost" icon="more-horizontal" />
</Dropdown>
</div>
</div>
<Dialog
v-model="show"
:options="{ size: '3xl', title: __('Nested conditions') }"
>
<template #body-content>
<CFConditions
:conditions="props.condition"
:isChild="true"
:level="props.level"
:disableAddCondition="props.disableAddCondition"
/>
</template>
</Dialog>
</template>
<script setup>
import {
Autocomplete,
Button,
DatePicker,
DateRangePicker,
DateTimePicker,
Dialog,
Dropdown,
FormControl,
Rating,
} from 'frappe-ui'
import { computed, defineEmits, h, ref } from 'vue'
import GroupIcon from '~icons/lucide/group'
import UnGroupIcon from '~icons/lucide/ungroup'
import CFConditions from './CFConditions.vue'
import { filterableFields } from './filterableFields'
import Link from '@/components/Controls/Link.vue'
const show = ref(false)
const emit = defineEmits([
'remove',
'unGroupConditions',
'toggleConjunction',
'turnIntoGroup',
])
const props = defineProps({
condition: {
type: Array,
required: true,
},
isChild: {
type: Boolean,
default: false,
},
itemIndex: {
type: Number,
},
level: {
type: Number,
default: 0,
},
isGroup: {
type: Boolean,
default: false,
},
conjunction: {
type: String,
},
disableAddCondition: {
type: Boolean,
default: false,
},
})
const dropdownOptions = computed(() => {
const options = []
if (!props.isGroup && props.level < 4) {
options.push({
label: __('Turn into a group'),
icon: () => h(GroupIcon),
onClick: () => {
emit('turnIntoGroup')
},
})
}
if (props.isGroup) {
options.push({
label: __('Ungroup conditions'),
icon: () => h(UnGroupIcon),
onClick: () => {
emit('unGroupConditions')
},
})
}
options.push({
label: __('Remove'),
icon: 'trash-2',
variant: 'red',
onClick: () => emit('remove'),
condition: () => !props.isGroup,
})
options.push({
label: __('Remove group'),
icon: 'trash-2',
variant: 'red',
onClick: () => emit('remove'),
condition: () => props.isGroup,
})
return options
})
const typeCheck = ['Check']
const typeLink = ['Link', 'Dynamic Link']
const typeNumber = ['Float', 'Int', 'Currency', 'Percent']
const typeSelect = ['Select']
const typeString = ['Data', 'Long Text', 'Small Text', 'Text Editor', 'Text']
const typeDate = ['Date', 'Datetime']
const typeRating = ['Rating']
function toggleConjunction() {
emit('toggleConjunction', props.conjunction)
}
const updateField = (field) => {
props.condition[0] = field?.fieldname
resetConditionValue()
}
const resetConditionValue = () => {
props.condition[2] = ''
}
function getValueControl() {
const [field, operator] = props.condition
if (!field) return null
const fieldData = filterableFields.data?.find((f) => f.fieldname == field)
if (!fieldData) return null
const { fieldtype, options } = fieldData
if (operator == 'is') {
return h(FormControl, {
type: 'select',
options: [
{
label: 'Set',
value: 'set',
},
{
label: 'Not Set',
value: 'not set',
},
],
})
} else if (['like', 'not like', 'in', 'not in'].includes(operator)) {
return h(FormControl, { type: 'text' })
} else if (typeSelect.includes(fieldtype) || typeCheck.includes(fieldtype)) {
const _options =
fieldtype == 'Check' ? ['Yes', 'No'] : getSelectOptions(options)
return h(FormControl, {
type: 'select',
options: _options.map((o) => ({
label: o,
value: o,
})),
})
} else if (typeLink.includes(fieldtype)) {
if (fieldtype == 'Dynamic Link') {
return h(FormControl, { type: 'text' })
}
return h(Link, {
class: 'form-control',
doctype: options,
value: props.condition[2],
})
} else if (typeNumber.includes(fieldtype)) {
return h(FormControl, { type: 'number' })
} else if (typeDate.includes(fieldtype) && operator == 'between') {
return h(DateRangePicker, { value: props.condition[2], iconLeft: '' })
} else if (typeDate.includes(fieldtype)) {
return h(fieldtype == 'Date' ? DatePicker : DateTimePicker, {
value: props.condition[2],
iconLeft: '',
})
} else if (typeRating.includes(fieldtype)) {
return h(Rating, {
modelValue: props.condition[2] || 0,
class: 'truncate',
'update:modelValue': (v) => updateValue(v),
})
} else {
return h(FormControl, { type: 'text' })
}
}
function updateValue(value) {
value = value.target ? value.target.value : value
if (props.condition[1] === 'between') {
props.condition[2] = [value.split(',')[0], value.split(',')[1]]
} else {
props.condition[2] = value + ''
}
}
function getSelectOptions(options) {
return options.split('\n')
}
function updateOperator(event) {
let oldOperatorValue = event.target._value
let newOperatorValue = event.target.value
props.condition[1] = event.target.value
if (!isSameTypeOperator(oldOperatorValue, newOperatorValue)) {
props.condition[2] = getDefaultValue(props.condition[0])
}
resetConditionValue()
}
function getOperators() {
let options = []
const field = props.condition[0]
if (!field) return options
const fieldData = filterableFields.data?.find((f) => f.fieldname == field)
if (!fieldData) return options
const { fieldtype, fieldname } = fieldData
if (typeString.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
{ label: 'In', value: 'in' },
{ label: 'Not In', value: 'not in' },
{ label: 'Is', value: 'is' },
],
)
}
if (fieldname === '_assign') {
options = [
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
{ label: 'Is', value: 'is' },
]
}
if (typeNumber.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
{ label: 'In', value: 'in' },
{ label: 'Not In', value: 'not in' },
{ label: 'Is', value: 'is' },
{ label: '<', value: '<' },
{ label: '>', value: '>' },
{ label: '<=', value: '<=' },
{ label: '>=', value: '>=' },
],
)
}
if (typeSelect.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'In', value: 'in' },
{ label: 'Not In', value: 'not in' },
{ label: 'Is', value: 'is' },
],
)
}
if (typeLink.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
{ label: 'In', value: 'in' },
{ label: 'Not In', value: 'not in' },
{ label: 'Is', value: 'is' },
],
)
}
if (typeCheck.includes(fieldtype)) {
options.push(...[{ label: 'Equals', value: '==' }])
}
if (['Duration'].includes(fieldtype)) {
options.push(
...[
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
{ label: 'In', value: 'in' },
{ label: 'Not In', value: 'not in' },
{ label: 'Is', value: 'is' },
],
)
}
if (typeDate.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'Is', value: 'is' },
{ label: '>', value: '>' },
{ label: '<', value: '<' },
{ label: '>=', value: '>=' },
{ label: '<=', value: '<=' },
{ label: 'Between', value: 'between' },
],
)
}
if (typeRating.includes(fieldtype)) {
options.push(
...[
{ label: 'Equals', value: '==' },
{ label: 'Not Equals', value: '!=' },
{ label: 'Is', value: 'is' },
{ label: '>', value: '>' },
{ label: '<', value: '<' },
{ label: '>=', value: '>=' },
{ label: '<=', value: '<=' },
],
)
}
const op = options.find((o) => o.value == props.condition[1])
props.condition[1] = op?.value || options[0].value
return options
}
function getDefaultValue(field) {
if (typeSelect.includes(field.fieldtype)) {
return getSelectOptions(field.options)[0]
}
if (typeCheck.includes(field.fieldtype)) {
return 'Yes'
}
if (typeDate.includes(field.fieldtype)) {
return null
}
if (typeRating.includes(field.fieldtype)) {
return 0
}
return ''
}
function isSameTypeOperator(oldOperator, newOperator) {
let textOperators = ['==', '!=', 'in', 'not in', '>', '<', '>=', '<=']
if (
textOperators.includes(oldOperator) &&
textOperators.includes(newOperator)
)
return true
return false
}
</script>

View File

@ -0,0 +1,142 @@
<template>
<div class="rounded-lg border border-outline-gray-2 p-3 flex flex-col gap-4 w-full">
<template v-for="(condition, i) in props.conditions" :key="condition.field">
<CFCondition
v-if="Array.isArray(condition)"
:condition="condition"
:isChild="props.isChild"
:itemIndex="i"
@remove="removeCondition(condition)"
@unGroupConditions="unGroupConditions(condition)"
:level="props.level + 1"
@toggleConjunction="toggleConjunction"
:isGroup="isGroupCondition(condition[0])"
:conjunction="getConjunction()"
@turnIntoGroup="turnIntoGroup(condition)"
:disableAddCondition="props.disableAddCondition"
/>
</template>
<div v-if="props.isChild" class="flex">
<Dropdown v-slot="{ open }" :options="dropdownOptions">
<Button
:disabled="props.disableAddCondition"
:label="__('Add condition')"
icon-left="plus"
:icon-right="open ? 'chevron-up' : 'chevron-down'"
/>
</Dropdown>
</div>
</div>
</template>
<script setup>
import { Button, Dropdown } from 'frappe-ui'
import { computed, watch } from 'vue'
import CFCondition from './CFCondition.vue'
import { filterableFields } from './filterableFields'
const props = defineProps({
conditions: {
type: Array,
required: true,
},
isChild: {
type: Boolean,
default: false,
},
level: {
type: Number,
default: 0,
},
disableAddCondition: {
type: Boolean,
default: false,
},
doctype: {
type: String,
required: true,
},
})
const getConjunction = () => {
let conjunction = 'and'
props.conditions.forEach((condition) => {
if (typeof condition == 'string') {
conjunction = condition
}
})
return conjunction
}
const turnIntoGroup = (condition) => {
props.conditions.splice(props.conditions.indexOf(condition), 1, [condition])
}
const isGroupCondition = (condition) => {
return Array.isArray(condition)
}
const dropdownOptions = computed(() => {
const options = [
{
label: __('Add condition'),
onClick: () => {
const conjunction = getConjunction()
props.conditions.push(conjunction, ['', '', ''])
},
},
]
if (props.level < 3) {
options.push({
label: __('Add condition group'),
onClick: () => {
const conjunction = getConjunction()
props.conditions.push(conjunction, [[]])
},
})
}
return options
})
function removeCondition(condition) {
const conditionIndex = props.conditions.indexOf(condition)
if (conditionIndex == 0) {
props.conditions.splice(conditionIndex, 2)
} else {
props.conditions.splice(conditionIndex - 1, 2)
}
}
function unGroupConditions(condition) {
const conjunction = getConjunction()
const newConditions = condition.map((c) => {
if (typeof c == 'string') {
return conjunction
}
return c
})
const index = props.conditions.indexOf(condition)
if (index !== -1) {
props.conditions.splice(index, 1, ...newConditions)
}
}
function toggleConjunction(conjunction) {
for (let i = 0; i < props.conditions.length; i++) {
if (typeof props.conditions[i] == 'string') {
props.conditions[i] = conjunction == 'and' ? 'or' : 'and'
}
}
}
watch(
() => props.doctype,
(doctype) => {
filterableFields.submit({
doctype,
})
},
{ immediate: true },
)
</script>

View File

@ -0,0 +1,17 @@
import { createResource } from 'frappe-ui'
export const filterableFields = createResource({
url: 'crm.api.doc.get_filterable_fields',
transform: (data) => {
data = data
.filter((field) => !field.fieldname.startsWith('_'))
.map((field) => {
return {
label: field.label,
value: field.fieldname,
...field,
}
})
return data
},
})

View File

@ -52,16 +52,14 @@
>
</div>
</div>
<div class="w-12">
<div class="flex items-center justify-center w-12">
<Button
class="flex w-full items-center justify-center rounded !bg-surface-gray-2 border-0"
:tooltip="__('Edit grid fields')"
class="rounded !bg-surface-gray-2 border-0 !text-ink-gray-5"
variant="outline"
icon="settings"
@click="showGridFieldsEditorModal = true"
>
<template #icon>
<FeatherIcon name="settings" class="size-4 text-ink-gray-7" />
</template>
</Button>
/>
</div>
</div>
<!-- Rows -->
@ -72,6 +70,7 @@
:delay="isTouchScreenDevice() ? 200 : 0"
group="rows"
item-key="name"
@end="reorder"
>
<template #item="{ element: row, index }">
<div
@ -277,16 +276,14 @@
/>
</div>
</div>
<div class="edit-row w-12">
<div class="edit-row flex items-center justify-center w-12">
<Button
class="flex w-full items-center justify-center rounded border-0"
:tooltip="__('Edit row')"
class="rounded border-0 !text-ink-gray-7"
variant="outline"
:icon="EditIcon"
@click="showRowList[index] = true"
>
<template #icon>
<EditIcon class="text-ink-gray-7" />
</template>
</Button>
/>
</div>
<GridRowModal
v-if="showRowList[index]"
@ -350,7 +347,6 @@ import { usersStore } from '@/stores/users'
import { getMeta } from '@/stores/meta'
import { createDocument } from '@/composables/document'
import {
FeatherIcon,
FormControl,
Checkbox,
DateTimePicker,
@ -520,6 +516,13 @@ const deleteRows = () => {
selectedRows.clear()
}
const reorder = () => {
rows.value.forEach((row, index) => {
row.idx = index + 1
})
}
function fieldChange(value, field, row) {
triggerOnChange(field.fieldname, value, row)
}

View File

@ -54,13 +54,10 @@
<template #target="{ togglePopover }">
<Button
class="w-full mt-2"
@click="togglePopover()"
:label="__('Add Field')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover()"
/>
</template>
<template #item-label="{ option }">
<div class="flex flex-col gap-1 text-ink-gray-9">
@ -75,7 +72,7 @@
</div>
</template>
<template #actions>
<div class="flex flex-col gap-2">
<div class="flex items-center gap-2 justify-end">
<Button
v-if="dirty"
class="w-full"

View File

@ -11,19 +11,18 @@
<div class="flex items-center gap-1">
<Button
v-if="isManager()"
:tooltip="__('Edit fields layout')"
variant="ghost"
class="w-7"
:icon="EditIcon"
@click="openGridRowFieldsModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
icon="x"
variant="ghost"
class="w-7"
@click="show = false"
/>
</div>
</div>
<div>

View File

@ -1,7 +1,6 @@
<template>
<FileUploader
:file-types="image_type"
class="text-base"
@success="
(file) => {
$emit('upload', file.file_url)
@ -10,21 +9,28 @@
>
<template v-slot="{ progress, uploading, openFileSelector }">
<div class="flex items-end space-x-1">
<Button @click="openFileSelector">
{{
<Button
@click="openFileSelector"
:iconLeft="uploading ? 'cloud-upload' : ImageUpIcon"
:label="
uploading
? `Uploading ${progress}%`
? __('Uploading {0}%', [progress])
: image_url
? 'Change'
: 'Upload'
}}
</Button>
<Button v-if="image_url" @click="$emit('remove')">Remove</Button>
? __('Change')
: __('Upload')
"
/>
<Button
v-if="image_url"
:label="__('Remove')"
@click="$emit('remove')"
/>
</div>
</template>
</FileUploader>
</template>
<script setup>
import ImageUpIcon from '~icons/lucide/image-up'
import { FileUploader, Button } from 'frappe-ui'
const prop = defineProps({
@ -33,10 +39,6 @@ const prop = defineProps({
type: String,
default: 'image/*',
},
label: {
type: String,
default: '',
},
})
const emit = defineEmits(['upload', 'remove'])
</script>

View File

@ -48,24 +48,18 @@
variant="ghost"
class="w-full !justify-start"
:label="__('Create New')"
iconLeft="plus"
@click="() => attrs.onCreate(value, close)"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
/>
</div>
<div>
<Button
variant="ghost"
class="w-full !justify-start"
:label="__('Clear')"
iconLeft="x"
@click="() => clearValue(close)"
>
<template #prefix>
<FeatherIcon name="x" class="h-4" />
</template>
</Button>
/>
</div>
</template>
</Autocomplete>

View File

@ -18,14 +18,10 @@
:key="g.label"
>
<Dropdown :options="g.action" v-slot="{ open }">
<Button :label="g.label">
<template #suffix>
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
class="h-4"
/>
</template>
</Button>
<Button
:label="g.label"
:iconRight="open ? 'chevron-up' : 'chevron-down'"
/>
</Dropdown>
</div>
</template>

View File

@ -2,7 +2,7 @@
<Dialog v-model="show" :options="{ size: 'xl' }">
<template #body v-if="!confirmDeleteInfo.show">
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
<div class="mb-4 flex items-center justify-between">
<div class="mb-6 flex items-center justify-between">
<div>
<h3 class="text-2xl leading-6 text-ink-gray-9 font-semibold">
{{
@ -32,11 +32,12 @@
{
label: 'Document',
key: 'title',
width: '19rem',
},
{
label: 'Master',
key: 'reference_doctype',
width: '30%',
width: '12rem',
},
]"
@selectionsChanged="

View File

@ -123,11 +123,12 @@
v-slot="{ togglePopover }"
@update:modelValue="() => appendEmoji()"
>
<Button variant="ghost" @click="togglePopover()">
<template #icon>
<SmileIcon class="h-4" />
</template>
</Button>
<Button
:tooltip="__('Insert Emoji')"
:icon="SmileIcon"
variant="ghost"
@click="togglePopover()"
/>
</IconPicker>
<FileUploader
:upload-args="{
@ -138,21 +139,20 @@
@success="(f) => attachments.push(f)"
>
<template #default="{ openFileSelector }">
<Button variant="ghost" @click="openFileSelector()">
<template #icon>
<AttachmentIcon class="h-4" />
</template>
</Button>
<Button
:tooltip="__('Attach a file')"
:icon="AttachmentIcon"
variant="ghost"
@click="openFileSelector()"
/>
</template>
</FileUploader>
<Button
:tooltip="__('Insert Email Template')"
variant="ghost"
:icon="EmailTemplateIcon"
@click="showEmailTemplateSelectorModal = true"
>
<template #icon>
<EmailTemplateIcon class="h-4" />
</template>
</Button>
/>
</div>
<div class="mt-2 flex items-center justify-end space-x-2 sm:mt-0">
<Button v-bind="discardButtonProps || {}" :label="__('Discard')" />

View File

@ -89,12 +89,9 @@
v-if="data[field.fieldname] && field.edit"
class="shrink-0"
:label="__('Edit')"
:iconLeft="EditIcon"
@click="field.edit(data[field.fieldname])"
>
<template #prefix>
<EditIcon class="h-4 w-4" />
</template>
</Button>
/>
</div>
<TableMultiselectInput

View File

@ -169,13 +169,10 @@
<Button
class="w-full !h-8 !bg-surface-modal"
variant="outline"
@click="togglePopover()"
:label="__('Add Field')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover()"
/>
</div>
</template>
<template #item-label="{ option }">
@ -198,6 +195,7 @@
class="w-full h-8"
variant="subtle"
:label="__('Add Section')"
iconLeft="plus"
@click="
tabs[tabIndex].sections.push({
label: __('New Section'),
@ -206,11 +204,7 @@
columns: [{ name: 'column_' + getRandom(), fields: [] }],
})
"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
/>
</div>
</div>
</div>

View File

@ -29,6 +29,7 @@
filesUploaderArea?.showWebLink || filesUploaderArea?.showCamera
"
:label="isMobileView ? __('Back') : __('Back to file upload')"
iconLeft="arrow-left"
@click="
() => {
filesUploaderArea.showWebLink = false
@ -37,11 +38,7 @@
filesUploaderArea.cameraImage = null
}
"
>
<template #prefix>
<FeatherIcon name="arrow-left" class="size-4" />
</template>
</Button>
/>
<Button
v-if="
filesUploaderArea?.showCamera && !filesUploaderArea?.cameraImage

View File

@ -1,12 +1,13 @@
<template>
<NestedPopover>
<template #target>
<Popover placement="bottom-end">
<template #target="{ togglePopover, close }">
<div class="flex items-center">
<Button
:label="__('Filter')"
:class="filters?.size ? 'rounded-r-none' : ''"
:iconLeft="FilterIcon"
@click="togglePopover"
>
<template #prefix><FilterIcon class="h-4" /></template>
<template v-if="filters?.size" #suffix>
<div
class="flex h-5 w-5 items-center justify-center rounded-[5px] bg-surface-white pt-px text-xs font-medium text-ink-gray-8 shadow-sm"
@ -15,15 +16,13 @@
</div>
</template>
</Button>
<Tooltip v-if="filters?.size" :text="__('Clear all Filter')">
<div>
<Button
class="rounded-l-none border-l"
icon="x"
@click.stop="clearfilter(false)"
/>
</div>
</Tooltip>
<Button
v-if="filters?.size"
:tooltip="__('Clear all Filter')"
class="rounded-l-none border-l"
icon="x"
@click.stop="clearfilter(close)"
/>
</div>
</template>
<template #body="{ close }">
@ -134,13 +133,10 @@
<Button
class="!text-ink-gray-5"
variant="ghost"
@click="togglePopover()"
:label="__('Add Filter')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover()"
/>
</template>
</Autocomplete>
<Button
@ -154,17 +150,16 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
import NestedPopover from '@/components/NestedPopover.vue'
import FilterIcon from '@/components/Icons/FilterIcon.vue'
import Link from '@/components/Controls/Link.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import {
FormControl,
createResource,
Tooltip,
Popover,
DatePicker,
DateTimePicker,
DateRangePicker,
@ -485,7 +480,7 @@ function removeFilter(index) {
function clearfilter(close) {
filters.value.clear()
apply()
close && close()
close()
}
function updateValue(value, filter) {

View File

@ -7,18 +7,10 @@
? groupByValue?.label
: __('Group By: ') + groupByValue?.label
"
:iconLeft="DetailsIcon"
:iconRight="isOpen ? 'chevron-up' : 'chevron-down'"
@click="togglePopover()"
>
<template #prefix>
<DetailsIcon />
</template>
<template #suffix>
<FeatherIcon
:name="isOpen ? 'chevron-up' : 'chevron-down'"
class="h-4"
/>
</template>
</Button>
/>
</template>
</Autocomplete>
</template>

View File

@ -69,7 +69,7 @@
</Popover>
</template>
<script setup>
import Popover from '@/components/frappe-ui/Popover.vue'
import { Popover } from 'frappe-ui'
import { gemoji } from 'gemoji'
import { ref, computed } from 'vue'

View File

@ -0,0 +1,19 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-settings2-icon lucide-settings-2"
>
<path d="M14 17H5" />
<path d="M19 7h-9" />
<circle cx="17" cy="17" r="3" />
<circle cx="7" cy="7" r="3" />
</svg>
</template>

View File

@ -0,0 +1,16 @@
<template>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M3.37543 1.93494L4.21632 2.21494C4.35232 2.26027 4.44388 2.38738 4.44388 2.53138C4.44388 2.67538 4.35143 2.80249 4.21543 2.84783L3.37454 3.12783L3.09365 3.9696C3.04921 4.10472 2.92121 4.19716 2.7781 4.19716C2.63499 4.19716 2.50787 4.1056 2.46254 3.9696L2.18165 3.12783L1.34076 2.84783C1.20476 2.80249 1.11232 2.67538 1.11232 2.53138C1.11232 2.38738 1.20476 2.26027 1.34076 2.21494L2.18165 1.93494L2.46254 1.09316C2.55321 0.82116 3.00387 0.82116 3.09454 1.09316L3.37543 1.93494ZM8.44852 1.33394C8.3643 1.16325 8.19046 1.05518 8.00012 1.05518C7.80978 1.05518 7.63595 1.16325 7.55173 1.33394L5.67697 5.13368L1.48388 5.74214C1.29552 5.76947 1.13901 5.90137 1.08017 6.08238C1.02133 6.26339 1.07036 6.46211 1.20665 6.59497L4.24065 9.55281L3.52421 13.7284C3.49203 13.916 3.56913 14.1056 3.7231 14.2174C3.87706 14.3293 4.08119 14.3441 4.24966 14.2555L8.11188 12.2253C8.35631 12.0968 8.4503 11.7945 8.32181 11.5501C8.19333 11.3057 7.89102 11.2117 7.64659 11.3402L4.68114 12.899L5.2707 9.46284C5.29853 9.30065 5.24477 9.13514 5.12693 9.02027L2.63025 6.58626L6.08082 6.08555C6.24373 6.06191 6.38457 5.95959 6.45741 5.81196L8.00012 2.6852L9.54284 5.81196C9.61568 5.95959 9.75652 6.06191 9.91943 6.08555L13.37 6.58625L11.6235 8.2887C11.4258 8.48146 11.4218 8.79802 11.6145 8.99575C11.8073 9.19349 12.1239 9.19752 12.3216 9.00476L14.7936 6.59498C14.9299 6.46212 14.9789 6.2634 14.9201 6.08239C14.8612 5.90138 14.7047 5.76947 14.5164 5.74214L10.3233 5.13368L8.44852 1.33394ZM13.4744 11.9911L12.3517 11.6168L11.9775 10.4942C11.8557 10.1315 11.2557 10.1315 11.1339 10.4942L10.7597 11.6168L9.63702 11.9911C9.45569 12.0515 9.33302 12.2213 9.33302 12.4124C9.33302 12.6035 9.45569 12.7733 9.63702 12.8337L10.7597 13.2079L11.1339 14.3306C11.1944 14.5119 11.365 14.6346 11.5561 14.6346C11.7472 14.6346 11.917 14.5119 11.9784 14.3306L12.3526 13.2079L13.4752 12.8337C13.6566 12.7733 13.7792 12.6035 13.7792 12.4124C13.7792 12.2213 13.6566 12.0515 13.4752 11.9911H13.4744ZM13.3333 2.88883C13.3333 3.25702 13.0349 3.5555 12.6667 3.5555C12.2985 3.5555 12 3.25702 12 2.88883C12 2.52064 12.2985 2.22217 12.6667 2.22217C13.0349 2.22217 13.3333 2.52064 13.3333 2.88883Z"
fill="currentColor"
/>
</svg>
</template>

View File

@ -3,11 +3,8 @@
:label="__('Kanban Settings')"
@click="showDialog = true"
v-bind="$attrs"
>
<template #prefix>
<KanbanIcon class="h-4" />
</template>
</Button>
:iconLeft="KanbanIcon"
/>
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
<template #body-content>
<div>
@ -23,8 +20,8 @@
<template #target="{ togglePopover }">
<Button
class="w-full !justify-start"
@click="togglePopover()"
:label="columnField.label"
@click="togglePopover()"
/>
</template>
</Autocomplete>
@ -80,13 +77,10 @@
<template #target="{ togglePopover }">
<Button
class="w-full mt-2"
@click="togglePopover()"
:label="__('Add Field')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover()"
/>
</template>
<template #item-label="{ option }">
<div class="flex flex-col gap-1 text-ink-gray-9">

View File

@ -15,17 +15,18 @@
>
<div class="flex gap-2 items-center group justify-between">
<div class="flex items-center text-base">
<NestedPopover>
<template #target>
<Popover>
<template #target="{ togglePopover }">
<Button
variant="ghost"
size="sm"
class="hover:!bg-surface-gray-2"
@click="togglePopover"
>
<IndicatorIcon :class="parseColor(column.column.color)" />
</Button>
</template>
<template #body="{ close }">
<template #body>
<div
class="flex flex-col gap-3 px-3 py-2.5 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
>
@ -48,7 +49,7 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
<div class="text-ink-gray-9">{{ column.column.name }}</div>
</div>
<div class="flex">
@ -153,13 +154,10 @@
<template #target="{ togglePopover }">
<Button
class="w-full mt-2.5 mb-1 mr-5"
@click="togglePopover()"
:label="__('Add Column')"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
iconLeft="plus"
@click="togglePopover()"
/>
</template>
</Autocomplete>
</div>
@ -167,11 +165,10 @@
</template>
<script setup>
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
import { isTouchScreenDevice, colors, parseColor } from '@/utils'
import Draggable from 'vuedraggable'
import { Dropdown } from 'frappe-ui'
import { Dropdown, Popover } from 'frappe-ui'
import { computed } from 'vue'
const props = defineProps({

View File

@ -3,8 +3,8 @@
class="relative flex h-full flex-col justify-between transition-all duration-300 ease-in-out"
:class="isSidebarCollapsed ? 'w-12' : 'w-[220px]'"
>
<div>
<UserDropdown class="p-2" :isCollapsed="isSidebarCollapsed" />
<div class="p-2">
<UserDropdown :isCollapsed="isSidebarCollapsed" />
</div>
<div class="flex-1 overflow-y-auto">
<div class="mb-3 flex flex-col">
@ -197,51 +197,50 @@ const isSidebarCollapsed = useStorage('isSidebarCollapsed', false)
const isFCSite = ref(window.is_fc_site)
const isDemoSite = ref(window.is_demo_site)
const allViews = computed(() => {
const links = [
{
label: 'Dashboard',
icon: LucideLayoutDashboard,
to: 'Dashboard',
condition: () => isManager(),
},
{
label: 'Leads',
icon: LeadsIcon,
to: 'Leads',
},
{
label: 'Deals',
icon: DealsIcon,
to: 'Deals',
},
{
label: 'Contacts',
icon: ContactsIcon,
to: 'Contacts',
},
{
label: 'Organizations',
icon: OrganizationsIcon,
to: 'Organizations',
},
{
label: 'Notes',
icon: NoteIcon,
to: 'Notes',
},
{
label: 'Tasks',
icon: TaskIcon,
to: 'Tasks',
},
{
label: 'Call Logs',
icon: PhoneIcon,
to: 'Call Logs',
},
]
const links = [
{
label: 'Dashboard',
icon: LucideLayoutDashboard,
to: 'Dashboard',
},
{
label: 'Leads',
icon: LeadsIcon,
to: 'Leads',
},
{
label: 'Deals',
icon: DealsIcon,
to: 'Deals',
},
{
label: 'Contacts',
icon: ContactsIcon,
to: 'Contacts',
},
{
label: 'Organizations',
icon: OrganizationsIcon,
to: 'Organizations',
},
{
label: 'Notes',
icon: NoteIcon,
to: 'Notes',
},
{
label: 'Tasks',
icon: TaskIcon,
to: 'Tasks',
},
{
label: 'Call Logs',
icon: PhoneIcon,
to: 'Call Logs',
},
]
const allViews = computed(() => {
let _views = [
{
name: 'All Views',

View File

@ -106,6 +106,8 @@ function convertToDeal(selections, unselectAll) {
}
function deleteValues(selections, unselectAll) {
unselectAllAction.value = unselectAll
const selectedDocs = Array.from(selections)
if (selectedDocs.length == 1) {
showDeleteDocModal.value = {
@ -217,6 +219,12 @@ function bulkActions(selections, unselectAll) {
}
function reload(unselectAll) {
showDeleteDocModal.value = {
showLinkedDocsModal: false,
showDeleteModal: false,
docname: null,
}
unselectAllAction.value?.()
unselectAll?.()
list.value?.reload()

View File

@ -26,13 +26,14 @@
<ListRowItem
:item="item"
@click="listViewRef.toggleRow(row['reference_docname'])"
class="!w-full"
>
<template #default="{ label }">
<div
v-if="column.key === 'title'"
class="truncate text-base flex gap-2"
class="truncate text-base flex gap-2 w-full"
>
<span>
<span class="max-w-[90%] truncate">
{{ label }}
</span>
<FeatherIcon
@ -102,6 +103,7 @@ const listViewRef = ref(null)
const viewLinkedDoc = (doc) => {
let page = ''
let id = ''
let openDesk = false
switch (doc.reference_doctype) {
case 'CRM Lead':
page = 'leads'
@ -123,6 +125,11 @@ const viewLinkedDoc = (doc) => {
page = 'organizations'
id = doc.reference_docname
break
case 'CRM Notification':
page = 'crm-notification'
id = doc.reference_docname
openDesk = true
break
case 'FCRM Note':
page = 'notes'
id = `view?open=${doc.reference_docname}`
@ -130,7 +137,11 @@ const viewLinkedDoc = (doc) => {
default:
break
}
window.open(`/crm/${page}/${id}`)
let base = '/crm'
if (openDesk) {
base = '/app'
}
window.open(`${base}/${page}/${id}`)
}
const getDoctypeName = (doctype) => {

View File

@ -11,19 +11,18 @@
<div class="flex items-center gap-1">
<Button
v-if="isManager() && !isMobileView"
:tooltip="__('Edit fields layout')"
variant="ghost"
:icon="EditIcon"
class="w-7"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
icon="x"
variant="ghost"
class="w-7"
@click="show = false"
/>
</div>
</div>
<div v-if="tabs.data && _address.doc">

View File

@ -36,18 +36,17 @@
<Button
v-if="!isMobileView"
variant="ghost"
:tooltip="__('Edit call log')"
:icon="EditIcon"
class="w-7"
@click="openCallLogModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
icon="x"
variant="ghost"
class="w-7"
@click="show = false"
/>
</div>
</div>
<div class="flex flex-col gap-3.5">

View File

@ -13,18 +13,17 @@
<Button
v-if="isManager() && !isMobileView"
variant="ghost"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
class="w-7"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
@click="show = false"
icon="x"
/>
</div>
</div>
<div v-if="tabs.data">
@ -37,7 +36,7 @@
</div>
</div>
<div class="px-4 pt-4 pb-7 sm:px-6">
<div class="space-y-2">
<div class="flex justify-end gap-2">
<Button
class="w-full"
v-for="action in dialogOptions.actions"
@ -61,7 +60,7 @@ import { showQuickEntryModal, quickEntryProps } from '@/composables/modals'
import { getRandom } from '@/utils'
import { capture } from '@/telemetry'
import { useDocument } from '@/data/document'
import { FeatherIcon, createResource, ErrorMessage, Badge } from 'frappe-ui'
import { createResource, ErrorMessage, Badge } from 'frappe-ui'
import { ref, nextTick, computed, onMounted } from 'vue'
const props = defineProps({

View File

@ -13,17 +13,16 @@
v-if="isManager() && !isMobileView"
variant="ghost"
class="w-7"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
@click="show = false"
icon="x"
/>
</div>
</div>
<FieldLayout
@ -90,12 +89,16 @@ const { document: _contact, triggerOnBeforeCreate } = useDocument('Contact')
async function createContact() {
if (_contact.doc.email_id) {
_contact.doc.email_ids = [{ email_id: _contact.doc.email_id, is_primary: 1 }]
_contact.doc.email_ids = [
{ email_id: _contact.doc.email_id, is_primary: 1 },
]
delete _contact.doc.email_id
}
if (_contact.doc.mobile_no) {
_contact.doc.phone_nos = [{ phone: _contact.doc.mobile_no, is_primary_mobile_no: 1 }]
_contact.doc.phone_nos = [
{ phone: _contact.doc.mobile_no, is_primary_mobile_no: 1 },
]
delete _contact.doc.mobile_no
}

View File

@ -1,17 +1,5 @@
<template>
<Dialog
v-model="show"
:options="{
size: 'xl',
actions: [
{
label: __('Convert'),
variant: 'solid',
onClick: convertToDeal,
},
],
}"
>
<Dialog v-model="show" :options="{ size: 'xl' }">
<template #body-header>
<div class="mb-6 flex items-center justify-between">
<div>
@ -23,12 +11,10 @@
<Button
v-if="isManager() && !isMobileView"
variant="ghost"
:tooltip="__('Edit deal\'s mandatory fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon class="h-4 w-4" />
</template>
</Button>
/>
<Button icon="x" variant="ghost" @click="show = false" />
</div>
</div>
@ -92,6 +78,11 @@
/>
<ErrorMessage class="mt-4" :message="error" />
</template>
<template #actions>
<div class="flex justify-end">
<Button :label="__('Convert')" variant="solid" @click="convertToDeal" />
</div>
</template>
</Dialog>
</template>
<script setup>

View File

@ -13,17 +13,16 @@
v-if="isManager() && !isMobileView"
variant="ghost"
class="w-7"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
icon="x"
@click="show = false"
/>
</div>
</div>
<div v-if="tabs.data">

View File

@ -13,17 +13,16 @@
v-if="isManager() && !isMobileView"
variant="ghost"
class="w-7"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
icon="x"
@click="show = false"
/>
</div>
</div>
<div>

View File

@ -13,17 +13,16 @@
v-if="isManager() && !isMobileView"
variant="ghost"
class="w-7"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
@click="show = false"
icon="x"
/>
</div>
</div>
<div>

View File

@ -1,45 +1,60 @@
<template>
<Dialog v-model="show" :options="{
size: 'xl',
actions: [
{
label: editMode ? __('Update') : __('Create'),
variant: 'solid',
onClick: () => updateNote(),
},
],
}">
<Dialog v-model="show" :options="{ size: 'xl' }">
<template #body-title>
<div class="flex items-center gap-3">
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
{{ editMode ? __('Edit Note') : __('Create Note') }}
</h3>
<Button v-if="_note?.reference_docname" size="sm" :label="_note.reference_doctype == 'CRM Deal'
? __('Open Deal')
: __('Open Lead')
" @click="redirect()">
<template #suffix>
<ArrowUpRightIcon class="w-4 h-4" />
</template>
</Button>
<Button
v-if="_note?.reference_docname"
size="sm"
:label="
_note.reference_doctype == 'CRM Deal'
? __('Open Deal')
: __('Open Lead')
"
:iconRight="ArrowUpRightIcon"
@click="redirect()"
/>
</div>
</template>
<template #body-content>
<div class="flex flex-col gap-4">
<div>
<FormControl ref="title" :label="__('Title')" v-model="_note.title" :placeholder="__('Call with John Doe')"
required />
<FormControl
ref="title"
:label="__('Title')"
v-model="_note.title"
:placeholder="__('Call with John Doe')"
required
/>
</div>
<div>
<div class="mb-1.5 text-xs text-ink-gray-5">{{ __('Content') }}</div>
<TextEditor variant="outline" ref="content"
<TextEditor
variant="outline"
ref="content"
editor-class="!prose-sm overflow-auto min-h-[180px] max-h-80 py-1.5 px-2 rounded border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-gray-modals hover:bg-surface-gray-3 hover:shadow-sm focus:bg-surface-white focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors"
:bubbleMenu="true" :content="_note.content" @change="(val) => (_note.content = val)" :placeholder="__('Took a call with John Doe and discussed the new project.')
" />
:bubbleMenu="true"
:content="_note.content"
@change="(val) => (_note.content = val)"
:placeholder="
__('Took a call with John Doe and discussed the new project.')
"
/>
</div>
<ErrorMessage class="mt-4" v-if="error" :message="__(error)" />
</div>
</template>
<template #actions>
<div class="flex justify-end">
<Button
:label="editMode ? __('Update') : __('Create')"
variant="solid"
@click="updateNote"
/>
</div>
</template>
</Dialog>
</template>
@ -92,21 +107,25 @@ async function updateNote() {
emit('after', d)
}
} else {
let d = await call('frappe.client.insert', {
doc: {
doctype: 'FCRM Note',
title: _note.value.title,
content: _note.value.content,
reference_doctype: props.doctype,
reference_docname: props.doc || '',
let d = await call(
'frappe.client.insert',
{
doc: {
doctype: 'FCRM Note',
title: _note.value.title,
content: _note.value.content,
reference_doctype: props.doctype,
reference_docname: props.doc || '',
},
},
}, {
onError: (err) => {
if (err.error.exc_type == 'MandatoryError') {
error.value = "Title is mandatory"
}
}
})
{
onError: (err) => {
if (err.error.exc_type == 'MandatoryError') {
error.value = 'Title is mandatory'
}
},
},
)
if (d.name) {
updateOnboardingStep('create_first_note')
capture('note_created')

View File

@ -13,17 +13,16 @@
v-if="isManager() && !isMobileView"
variant="ghost"
class="w-7"
:tooltip="__('Edit fields layout')"
:icon="EditIcon"
@click="openQuickEntryModal"
>
<template #icon>
<EditIcon />
</template>
</Button>
<Button variant="ghost" class="w-7" @click="show = false">
<template #icon>
<FeatherIcon name="x" class="size-4" />
</template>
</Button>
/>
<Button
variant="ghost"
class="w-7"
@click="show = false"
icon="x"
/>
</div>
</div>
<FieldLayout
@ -109,6 +108,7 @@ async function createOrganization() {
onError: (err) => {
if (err.error.exc_type == 'ValidationError') {
error.value = err.error?.messages?.[0]
loading.value = false
}
},
},
@ -175,6 +175,5 @@ function openAddressModal(_address) {
doctype: 'Address',
address: _address,
}
nextTick(() => (show.value = false))
}
</script>

View File

@ -1,17 +1,5 @@
<template>
<Dialog
v-model="show"
:options="{
size: 'xl',
actions: [
{
label: editMode ? __('Update') : __('Create'),
variant: 'solid',
onClick: () => updateTask(),
},
],
}"
>
<Dialog v-model="show" :options="{ size: 'xl' }">
<template #body-title>
<div class="flex items-center gap-3">
<h3 class="text-2xl font-semibold leading-6 text-ink-gray-9">
@ -25,12 +13,9 @@
? __('Open Deal')
: __('Open Lead')
"
:iconRight="ArrowUpRightIcon"
@click="redirect()"
>
<template #suffix>
<ArrowUpRightIcon class="w-4 h-4" />
</template>
</Button>
/>
</div>
</template>
<template #body-content>
@ -62,7 +47,7 @@
</div>
<div class="flex flex-wrap items-center gap-2">
<Dropdown :options="taskStatusOptions(updateTaskStatus)">
<Button :label="_task.status" class="justify-between w-full">
<Button :label="_task.status">
<template #prefix>
<TaskStatusIcon :status="_task.status" />
</template>
@ -93,15 +78,17 @@
</Tooltip>
</template>
</Link>
<DateTimePicker
class="datepicker w-36"
v-model="_task.due_date"
:placeholder="__('01/04/2024 11:30 PM')"
:formatter="(date) => getFormat(date, '', true, true)"
input-class="border-none"
/>
<div class="w-36">
<DateTimePicker
class="datepicker"
v-model="_task.due_date"
:placeholder="__('01/04/2024 11:30 PM')"
:formatter="(date) => getFormat(date, '', true, true)"
input-class="border-none"
/>
</div>
<Dropdown :options="taskPriorityOptions(updateTaskPriority)">
<Button :label="_task.priority" class="justify-between w-full">
<Button :label="_task.priority">
<template #prefix>
<TaskPriorityIcon :priority="_task.priority" />
</template>
@ -111,6 +98,15 @@
<ErrorMessage class="mt-4" v-if="error" :message="__(error)" />
</div>
</template>
<template #actions>
<div class="flex justify-end">
<Button
:label="editMode ? __('Update') : __('Create')"
variant="solid"
@click="updateTask"
/>
</div>
</template>
</Dialog>
</template>

View File

@ -7,17 +7,6 @@
: duplicateMode
? __('Duplicate View')
: __('Create View'),
actions: [
{
label: editMode
? __('Save Changes')
: duplicateMode
? __('Duplicate')
: __('Create'),
variant: 'solid',
onClick: () => (editMode ? update() : create()),
},
],
}"
>
<template #body-content>
@ -42,6 +31,21 @@
/>
</div>
</template>
<template #actions>
<div class="flex justify-end">
<Button
variant="solid"
:label="
editMode
? __('Save Changes')
: duplicateMode
? __('Duplicate')
: __('Create')
"
@click="() => (editMode ? update() : create())"
/>
</div>
</template>
</Dialog>
</template>

View File

@ -9,21 +9,9 @@
$attrs.class,
showDropdown ? 'rounded-br-none rounded-tr-none' : '',
]"
:iconLeft="activeButton.icon"
@click="() => activeButton.onClick()"
>
<template #prefix>
<FeatherIcon
v-if="activeButton.icon && typeof activeButton.icon === 'string'"
:name="activeButton.icon"
class="h-4 w-4"
/>
<component
v-else-if="activeButton.icon"
:is="activeButton.icon"
class="h-4 w-4"
/>
</template>
</Button>
/>
<Dropdown
v-if="showDropdown"
:options="parsedOptions"
@ -54,7 +42,6 @@ const showDropdown = ref(props.options?.length > 1)
const activeButton = ref(props.options?.[0] || {})
const parsedOptions = computed(() => {
debugger
return (
props.options?.map((option) => {
return {

View File

@ -1,60 +0,0 @@
<template>
<Popover v-slot="{ open }">
<PopoverButton
as="div"
ref="reference"
@click="updatePosition"
@focusin="updatePosition"
@keydown="updatePosition"
v-slot="{ open }"
>
<slot name="target" v-bind="{ open }" />
</PopoverButton>
<div v-show="open">
<PopoverPanel
v-slot="{ open, close }"
ref="popover"
static
class="z-[100]"
>
<slot name="body" v-bind="{ open, close }" />
</PopoverPanel>
</div>
</Popover>
</template>
<script setup>
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
import { createPopper } from '@popperjs/core'
import { nextTick, ref, onBeforeUnmount } from 'vue'
const props = defineProps({
placement: {
type: String,
default: 'bottom-start',
},
})
const reference = ref(null)
const popover = ref(null)
let popper = ref(null)
function setupPopper() {
if (!popper.value) {
popper.value = createPopper(reference.value.el, popover.value.el, {
placement: props.placement,
})
} else {
popper.value.update()
}
}
function updatePosition() {
nextTick(() => setupPopper())
}
onBeforeUnmount(() => {
popper.value?.destroy()
})
</script>

View File

@ -16,24 +16,18 @@
>
<div class="text-base font-medium">{{ __('Notifications') }}</div>
<div class="flex gap-1">
<Tooltip :text="__('Mark all as read')">
<div>
<Button variant="ghost" @click="() => markAllAsRead()">
<template #icon>
<MarkAsDoneIcon class="h-4 w-4" />
</template>
</Button>
</div>
</Tooltip>
<Tooltip :text="__('Close')">
<div>
<Button variant="ghost" @click="() => toggle()">
<template #icon>
<FeatherIcon name="x" class="h-4 w-4" />
</template>
</Button>
</div>
</Tooltip>
<Button
:tooltip="__('Mark all as read')"
:icon="MarkAsDoneIcon"
variant="ghost"
@click="markAllAsRead"
/>
<Button
:tooltip="__('Close')"
icon="x"
variant="ghost"
@click="() => toggle()"
/>
</div>
</div>
<div
@ -100,7 +94,6 @@ import { globalStore } from '@/stores/global'
import { timeAgo } from '@/utils'
import { onClickOutside } from '@vueuse/core'
import { capture } from '@/telemetry'
import { Tooltip } from 'frappe-ui'
import { ref, onMounted, onBeforeUnmount } from 'vue'
const { $socket } = globalStore()

View File

@ -0,0 +1,69 @@
<template>
<Popover>
<template #target="{ isOpen, togglePopover }">
<Button
:label="value"
class="dropdown-button flex items-center justify-between bg-surface-white !px-2.5 py-1.5 text-base text-ink-gray-8 placeholder-ink-gray-4 transition-colors hover:bg-surface-white focus:bg-surface-white focus:shadow-sm focus:outline-none focus:ring-0"
@click="togglePopover"
>
<div v-if="value" class="truncate">{{ value }}</div>
<div v-else class="text-base leading-5 text-ink-gray-4 truncate">
{{ placeholder }}
</div>
<template #suffix>
<FeatherIcon
:name="isOpen ? 'chevron-up' : 'chevron-down'"
class="h-4 text-ink-gray-5"
/>
</template>
</Button>
</template>
<template #body>
<div
class="my-2 p-1.5 min-w-40 space-y-1.5 divide-y divide-outline-gray-1 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
>
<div>
<PrimaryDropdownItem
v-for="option in options"
:key="option.name || option.value"
:option="option"
/>
<div v-if="!options?.length">
<div class="p-1.5 pl-3 pr-4 text-base text-ink-gray-4">
{{ __('No {0} Available', [label]) }}
</div>
</div>
</div>
<div class="pt-1.5">
<Button
variant="ghost"
class="w-full !justify-start"
:label="__('Create New')"
iconLeft="plus"
@click="create && create()"
/>
</div>
</div>
</template>
</Popover>
</template>
<script setup>
import PrimaryDropdownItem from '@/components/PrimaryDropdownItem.vue'
import { Popover } from 'frappe-ui'
const props = defineProps({
value: { type: [String, Number], default: '' },
placeholder: { type: String, default: '' },
options: { type: Array, default: [] },
create: { type: Function },
label: { type: String, default: '' },
})
</script>
<style scoped>
.dropdown-button {
border-color: transparent;
background: transparent;
}
</style>

View File

@ -19,53 +19,36 @@
v-if="editMode"
variant="ghost"
:label="__('Save')"
size="sm"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="saveOption"
/>
<Tooltip text="Set As Primary" v-if="!isNew && !option.selected">
<div>
<Button
variant="ghost"
size="sm"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="option.onClick"
>
<template #icon>
<SuccessIcon />
</template>
</Button>
</div>
</Tooltip>
<Tooltip v-if="!editMode" text="Edit">
<div>
<Button
variant="ghost"
size="sm"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="toggleEditMode"
>
<template #icon>
<EditIcon />
</template>
</Button>
</div>
</Tooltip>
<Tooltip text="Delete">
<div>
<Button
variant="ghost"
icon="x"
size="sm"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="() => option.onDelete(option, isNew)"
/>
</div>
</Tooltip>
<Button
v-if="!isNew && !option.selected"
:tooltip="__('Set As Primary')"
variant="ghost"
:icon="SuccessIcon"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="option.onClick"
/>
<Button
v-if="!editMode"
:tooltip="__('Edit')"
variant="ghost"
:icon="EditIcon"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="toggleEditMode"
/>
<Button
:tooltip="__('Delete')"
variant="ghost"
icon="x"
class="opacity-0 hover:bg-surface-gray-4 group-hover:opacity-100"
@click="() => option.onDelete(option, isNew)"
/>
</div>
</div>
<div v-if="option.selected">
<FeatherIcon name="check" class="text-ink-gray-5 h-4 w-6" size="sm" />
<FeatherIcon name="check" class="text-ink-gray-5 h-4 w-6" />
</div>
</div>
</template>
@ -73,7 +56,7 @@
<script setup>
import SuccessIcon from '@/components/Icons/SuccessIcon.vue'
import EditIcon from '@/components/Icons/EditIcon.vue'
import { TextInput, Tooltip } from 'frappe-ui'
import { TextInput } from 'frappe-ui'
import { nextTick, ref, onMounted } from 'vue'
const props = defineProps({

Some files were not shown because too many files have changed in this diff Show More