Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2021-12-06 16:07:08 +06:00 committed by GitHub
parent 7b70244f63
commit f5a2c55833
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
94 changed files with 1503 additions and 474 deletions

View File

@ -8,6 +8,9 @@ specifiers:
'@rush-temp/activity': file:./projects/activity.tgz '@rush-temp/activity': file:./projects/activity.tgz
'@rush-temp/activity-assets': file:./projects/activity-assets.tgz '@rush-temp/activity-assets': file:./projects/activity-assets.tgz
'@rush-temp/activity-resources': file:./projects/activity-resources.tgz '@rush-temp/activity-resources': file:./projects/activity-resources.tgz
'@rush-temp/attachment': file:./projects/attachment.tgz
'@rush-temp/attachment-assets': file:./projects/attachment-assets.tgz
'@rush-temp/attachment-resources': file:./projects/attachment-resources.tgz
'@rush-temp/chunter': file:./projects/chunter.tgz '@rush-temp/chunter': file:./projects/chunter.tgz
'@rush-temp/chunter-assets': file:./projects/chunter-assets.tgz '@rush-temp/chunter-assets': file:./projects/chunter-assets.tgz
'@rush-temp/chunter-resources': file:./projects/chunter-resources.tgz '@rush-temp/chunter-resources': file:./projects/chunter-resources.tgz
@ -33,6 +36,7 @@ specifiers:
'@rush-temp/model': file:./projects/model.tgz '@rush-temp/model': file:./projects/model.tgz
'@rush-temp/model-activity': file:./projects/model-activity.tgz '@rush-temp/model-activity': file:./projects/model-activity.tgz
'@rush-temp/model-all': file:./projects/model-all.tgz '@rush-temp/model-all': file:./projects/model-all.tgz
'@rush-temp/model-attachment': file:./projects/model-attachment.tgz
'@rush-temp/model-chunter': file:./projects/model-chunter.tgz '@rush-temp/model-chunter': file:./projects/model-chunter.tgz
'@rush-temp/model-contact': file:./projects/model-contact.tgz '@rush-temp/model-contact': file:./projects/model-contact.tgz
'@rush-temp/model-core': file:./projects/model-core.tgz '@rush-temp/model-core': file:./projects/model-core.tgz
@ -164,6 +168,9 @@ dependencies:
'@rush-temp/activity': file:projects/activity.tgz '@rush-temp/activity': file:projects/activity.tgz
'@rush-temp/activity-assets': file:projects/activity-assets.tgz '@rush-temp/activity-assets': file:projects/activity-assets.tgz
'@rush-temp/activity-resources': file:projects/activity-resources.tgz_476f694f64637160ae71e12ff57815b9 '@rush-temp/activity-resources': file:projects/activity-resources.tgz_476f694f64637160ae71e12ff57815b9
'@rush-temp/attachment': file:projects/attachment.tgz
'@rush-temp/attachment-assets': file:projects/attachment-assets.tgz
'@rush-temp/attachment-resources': file:projects/attachment-resources.tgz_476f694f64637160ae71e12ff57815b9
'@rush-temp/chunter': file:projects/chunter.tgz '@rush-temp/chunter': file:projects/chunter.tgz
'@rush-temp/chunter-assets': file:projects/chunter-assets.tgz '@rush-temp/chunter-assets': file:projects/chunter-assets.tgz
'@rush-temp/chunter-resources': file:projects/chunter-resources.tgz_476f694f64637160ae71e12ff57815b9 '@rush-temp/chunter-resources': file:projects/chunter-resources.tgz_476f694f64637160ae71e12ff57815b9
@ -189,6 +196,7 @@ dependencies:
'@rush-temp/model': file:projects/model.tgz '@rush-temp/model': file:projects/model.tgz
'@rush-temp/model-activity': file:projects/model-activity.tgz_typescript@4.4.3 '@rush-temp/model-activity': file:projects/model-activity.tgz_typescript@4.4.3
'@rush-temp/model-all': file:projects/model-all.tgz_typescript@4.4.3 '@rush-temp/model-all': file:projects/model-all.tgz_typescript@4.4.3
'@rush-temp/model-attachment': file:projects/model-attachment.tgz_typescript@4.4.3
'@rush-temp/model-chunter': file:projects/model-chunter.tgz_typescript@4.4.3 '@rush-temp/model-chunter': file:projects/model-chunter.tgz_typescript@4.4.3
'@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.4.3 '@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.4.3
'@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.4.3 '@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.4.3
@ -9620,6 +9628,68 @@ packages:
- supports-color - supports-color
dev: false dev: false
file:projects/attachment-assets.tgz:
resolution: {integrity: sha512-FCyg6p/pZjhvZBTdfmGWisxtakixI3vRpGTNGQDRYb/BvSE+GDNYuvPpXmD6HrMh+5sGfcZDMyWhtyGV9/ZqUA==, tarball: file:projects/attachment-assets.tgz}
name: '@rush-temp/attachment-assets'
version: 0.0.0
dev: false
file:projects/attachment-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-MRImst0WyxQ5iFxrOLL2P6aD9s4GXYtxPdTbCFcUDsqut/jxCWmIfHYIcuNOq/m2M4EEvqjhq4W/jOOf9215Fw==, tarball: file:projects/attachment-resources.tgz}
id: file:projects/attachment-resources.tgz
name: '@rush-temp/attachment-resources'
version: 0.0.0
dependencies:
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_05a8ea1454e6ca4c9f98b94b8f3abf9c
eslint-plugin-import: 2.25.3_eslint@7.32.0
eslint-plugin-node: 11.1.0_eslint@7.32.0
eslint-plugin-promise: 5.1.1_eslint@7.32.0
eslint-plugin-svelte3: 3.2.1_eslint@7.32.0+svelte@3.43.1
filesize: 8.0.3
prettier: 2.4.1
prettier-plugin-svelte: 2.5.0_prettier@2.4.1+svelte@3.43.1
sass: 1.42.1
svelte: 3.43.1
svelte-check: 2.2.10_3708ed3db7329f2cbf76db19160094b1
svelte-loader: 3.1.2_svelte@3.43.1
svelte-preprocess: 4.9.8_b1ccfb371c7d68f75291f5a547be0b14
typescript: 4.4.3
transitivePeerDependencies:
- '@babel/core'
- coffeescript
- less
- node-sass
- postcss
- postcss-load-config
- pug
- stylus
- sugarss
- supports-color
dev: false
file:projects/attachment.tgz:
resolution: {integrity: sha512-H3VFLgdb1nVXMPAjrqIhAD2Rtb56WTVDSXIIwAB2YoANkn4UIta8+SLtkqsUbFITiEpRu/qXA1S+LzenAoPCWg==, tarball: file:projects/attachment.tgz}
name: '@rush-temp/attachment'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.41.1
'@types/heft-jest': 1.0.2
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_05a8ea1454e6ca4c9f98b94b8f3abf9c
eslint-plugin-import: 2.25.3_eslint@7.32.0
eslint-plugin-node: 11.1.0_eslint@7.32.0
eslint-plugin-promise: 5.1.1_eslint@7.32.0
prettier: 2.4.1
typescript: 4.4.3
transitivePeerDependencies:
- supports-color
dev: false
file:projects/chunter-assets.tgz: file:projects/chunter-assets.tgz:
resolution: {integrity: sha512-kMTEO1cP8cmeoA2tImDBtT2SXfjo4AW0MWEbzFvzhZkLZaMmJGtl5ZHclKn/Wwg/LBA1zDc21fKlpeahmuNS4A==, tarball: file:projects/chunter-assets.tgz} resolution: {integrity: sha512-kMTEO1cP8cmeoA2tImDBtT2SXfjo4AW0MWEbzFvzhZkLZaMmJGtl5ZHclKn/Wwg/LBA1zDc21fKlpeahmuNS4A==, tarball: file:projects/chunter-assets.tgz}
name: '@rush-temp/chunter-assets' name: '@rush-temp/chunter-assets'
@ -9627,7 +9697,7 @@ packages:
dev: false dev: false
file:projects/chunter-resources.tgz_476f694f64637160ae71e12ff57815b9: file:projects/chunter-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-VeAPHIR/LZrUXIcd4AYBi4knK8+ZRnIGUd3ag30ILGm4kQ5b1hQXaHpBhSVwSqFktr4vlIoPACZudN7ChHKSqw==, tarball: file:projects/chunter-resources.tgz} resolution: {integrity: sha512-f6XU3bEnmm8jO7FEfi+LjEhLu4p/f8Y4HzoRHA+p39bZCegxBevjz89RWVFhQ+lC9tWWyg2zK0Tt6E88llN2lw==, tarball: file:projects/chunter-resources.tgz}
id: file:projects/chunter-resources.tgz id: file:projects/chunter-resources.tgz
name: '@rush-temp/chunter-resources' name: '@rush-temp/chunter-resources'
version: 0.0.0 version: 0.0.0
@ -9729,7 +9799,7 @@ packages:
dev: false dev: false
file:projects/contact-resources.tgz_476f694f64637160ae71e12ff57815b9: file:projects/contact-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-LIvMtKOFKmRTJCDkCpRIiUChzMX8x54RZAA0yVBbv8rt3HG7eKRxqAzeK5gbUp8vrcZLeNrpGy9/xqG5UHbkBQ==, tarball: file:projects/contact-resources.tgz} resolution: {integrity: sha512-7wNt7czMMNeogqSzQY1zCG/iOrTKKY6R52gyFcBxxBGUJtRWj7b7s8JtJ137tP0jZTcLlzhd99utKewQ/BkxQQ==, tarball: file:projects/contact-resources.tgz}
id: file:projects/contact-resources.tgz id: file:projects/contact-resources.tgz
name: '@rush-temp/contact-resources' name: '@rush-temp/contact-resources'
version: 0.0.0 version: 0.0.0
@ -10019,7 +10089,7 @@ packages:
dev: false dev: false
file:projects/front.tgz: file:projects/front.tgz:
resolution: {integrity: sha512-N1wFWaSW9qYwHTtlnqNdVByzFVkRtE5kOIg+IAnHiCcOSeYBGdE+V+pt/DohnpmpzEzxTR8jKUyYHusazAO+Mg==, tarball: file:projects/front.tgz} resolution: {integrity: sha512-iSBgFbScuEX0S/r4FJh/z02rKgeaMPKCe0Z7Unr/g2AzgeO65k1G6uaT/mtlr1ulaYixN+dMMmaxzkJT5psDeQ==, tarball: file:projects/front.tgz}
name: '@rush-temp/front' name: '@rush-temp/front'
version: 0.0.0 version: 0.0.0
dependencies: dependencies:
@ -10134,7 +10204,7 @@ packages:
dev: false dev: false
file:projects/model-all.tgz_typescript@4.4.3: file:projects/model-all.tgz_typescript@4.4.3:
resolution: {integrity: sha512-CmX0IDsPS79BtfPfKmxiiV8RYuxi+tx7r0UWxqk5zhln5FHF6Fi+cuuUyDmGZ6lYWp8x2q6reBcUdU8WRyJBEg==, tarball: file:projects/model-all.tgz} resolution: {integrity: sha512-76M/a9+Fy3fVPPgQDAPzjvn4b5KY2+VlRURicy5qStQDzRLmNHefnOdDDCxgO3eU/99TMnN6a+11Gjeu7NM/6w==, tarball: file:projects/model-all.tgz}
id: file:projects/model-all.tgz id: file:projects/model-all.tgz
name: '@rush-temp/model-all' name: '@rush-temp/model-all'
version: 0.0.0 version: 0.0.0
@ -10158,6 +10228,27 @@ packages:
- typescript - typescript
dev: false dev: false
file:projects/model-attachment.tgz_typescript@4.4.3:
resolution: {integrity: sha512-EKpkJcrMm3iEran7CFmmNoYX9ANHWts0PClN+OeqFyY/LGbEfQ7iciwDWlIuo9Br3u3m79jy6jTCTI/c08X4KA==, tarball: file:projects/model-attachment.tgz}
id: file:projects/model-attachment.tgz
name: '@rush-temp/model-attachment'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.41.1
'@types/heft-jest': 1.0.2
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_05a8ea1454e6ca4c9f98b94b8f3abf9c
eslint-plugin-import: 2.25.3_eslint@7.32.0
eslint-plugin-node: 11.1.0_eslint@7.32.0
eslint-plugin-promise: 5.1.1_eslint@7.32.0
prettier: 2.4.1
transitivePeerDependencies:
- supports-color
- typescript
dev: false
file:projects/model-chunter.tgz_typescript@4.4.3: file:projects/model-chunter.tgz_typescript@4.4.3:
resolution: {integrity: sha512-iB/GGhZOSuGpbKDb2jrxcj5dvndn1Hy61BV3dSxrZf/lBCoaA4SZfd66gWsdBsv17AOMmaWUvFJxxR5S6J2yfg==, tarball: file:projects/model-chunter.tgz} resolution: {integrity: sha512-iB/GGhZOSuGpbKDb2jrxcj5dvndn1Hy61BV3dSxrZf/lBCoaA4SZfd66gWsdBsv17AOMmaWUvFJxxR5S6J2yfg==, tarball: file:projects/model-chunter.tgz}
id: file:projects/model-chunter.tgz id: file:projects/model-chunter.tgz
@ -10180,7 +10271,7 @@ packages:
dev: false dev: false
file:projects/model-contact.tgz_typescript@4.4.3: file:projects/model-contact.tgz_typescript@4.4.3:
resolution: {integrity: sha512-naHvZqwC/GQIqo8xgCUOhovUx/M0ZkyRo/2YZsENMfbDoxnrKvpP+viOJiTLVoMP2yTE1/EGqSviQClNvJWcqw==, tarball: file:projects/model-contact.tgz} resolution: {integrity: sha512-85D68dBZHoPJbRnEythE2CGzp1qbwJ3ynLnBaf3TtNvlgukH1NT15fp2zD8W/4RK9QIscv65yO9gAjTeqjxHUw==, tarball: file:projects/model-contact.tgz}
id: file:projects/model-contact.tgz id: file:projects/model-contact.tgz
name: '@rush-temp/model-contact' name: '@rush-temp/model-contact'
version: 0.0.0 version: 0.0.0
@ -10243,7 +10334,7 @@ packages:
dev: false dev: false
file:projects/model-recruit.tgz_typescript@4.4.3: file:projects/model-recruit.tgz_typescript@4.4.3:
resolution: {integrity: sha512-tvZVIcVZxLJTwI6RVvuk1XXGOGcMji5VFeDQCzhJSif+2dPJIQHEe/HrxNKArqvOXhGyOaA6zbUpftdlAxjQ+A==, tarball: file:projects/model-recruit.tgz} resolution: {integrity: sha512-Ja9/9aH8v2JSQzsEtuxG7DFOOB405EoASN2ex9S31NYhYqgIqM8ZaRi5McthYz1e4gkyWFWtOCTHbBccNNOvLg==, tarball: file:projects/model-recruit.tgz}
id: file:projects/model-recruit.tgz id: file:projects/model-recruit.tgz
name: '@rush-temp/model-recruit' name: '@rush-temp/model-recruit'
version: 0.0.0 version: 0.0.0
@ -10388,7 +10479,7 @@ packages:
dev: false dev: false
file:projects/model-task.tgz_typescript@4.4.3: file:projects/model-task.tgz_typescript@4.4.3:
resolution: {integrity: sha512-7NTZP389oZgueMDG5WTRhgRWuT3VehxnJ5BqV2uWd/M8Yq8SGyIvyqN1vYiRBSkbksGcc+AMxbenH9eGZESB0g==, tarball: file:projects/model-task.tgz} resolution: {integrity: sha512-AjQvZTFE3GR6hQkU4jFA9M0bJhQhiiBIaZdW+2ALaj3xwAzolD6eSStCUWVWIZgj9uJTSfT8oGTiIw+iISB61Q==, tarball: file:projects/model-task.tgz}
id: file:projects/model-task.tgz id: file:projects/model-task.tgz
name: '@rush-temp/model-task' name: '@rush-temp/model-task'
version: 0.0.0 version: 0.0.0
@ -10661,7 +10752,7 @@ packages:
dev: false dev: false
file:projects/prod.tgz_sass@1.42.1+typescript@4.4.3: file:projects/prod.tgz_sass@1.42.1+typescript@4.4.3:
resolution: {integrity: sha512-YXR+9ndU1ibNRBgBG2s//HcelDIJmxvXqSPkrZ1A9z8qhjtnYGi7mwqIKpxS+mYVr5nS6JRCNLXcblAp7aDlXA==, tarball: file:projects/prod.tgz} resolution: {integrity: sha512-BsM4OYUp0S0TI6LsvclxVQ0kG6U9Oj4gbGbD38jUPIy02pVP82bS2WrAWh7/s3H4j+sbUnmmrVRulaDAcw34rw==, tarball: file:projects/prod.tgz}
id: file:projects/prod.tgz id: file:projects/prod.tgz
name: '@rush-temp/prod' name: '@rush-temp/prod'
version: 0.0.0 version: 0.0.0
@ -10735,7 +10826,7 @@ packages:
dev: false dev: false
file:projects/recruit-resources.tgz_476f694f64637160ae71e12ff57815b9: file:projects/recruit-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-nYgz+aOKNZBwy/q+w0H+/YSchx4IUQZOsnQJka38VLb8V35Oa9HoHDH5GgF79P+af2fN/pkeaR7T0+zhLd8DFQ==, tarball: file:projects/recruit-resources.tgz} resolution: {integrity: sha512-jJZMXXqVj+ovkyBhJrgToGioIbSmbf7otw3GrGcO/SuZ87j21EZHEY5vKaFAhuXDOriTz7UeajmGmUsx2H7okA==, tarball: file:projects/recruit-resources.tgz}
id: file:projects/recruit-resources.tgz id: file:projects/recruit-resources.tgz
name: '@rush-temp/recruit-resources' name: '@rush-temp/recruit-resources'
version: 0.0.0 version: 0.0.0
@ -10995,7 +11086,7 @@ packages:
dev: false dev: false
file:projects/setting-resources.tgz_476f694f64637160ae71e12ff57815b9: file:projects/setting-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-e9o9HTlJB1bBfRUN5KLhi/nJVaQqV1iFxOvISqV4hCLdMvf0+Yl7LkFqymZj9Oj277JV1HhO+VpSyPORtJcWaA==, tarball: file:projects/setting-resources.tgz} resolution: {integrity: sha512-I85L1AQz7schJl8/PKyTjw+/svzxhQ9xnlHSQQnMffB1cSQ265P1v7Zt+NERnsqLGD/l3c59nqXep8JrSDf/Tw==, tarball: file:projects/setting-resources.tgz}
id: file:projects/setting-resources.tgz id: file:projects/setting-resources.tgz
name: '@rush-temp/setting-resources' name: '@rush-temp/setting-resources'
version: 0.0.0 version: 0.0.0
@ -11056,7 +11147,7 @@ packages:
dev: false dev: false
file:projects/task-resources.tgz_e1367da94684b005adf08f025c517b1a: file:projects/task-resources.tgz_e1367da94684b005adf08f025c517b1a:
resolution: {integrity: sha512-ClICw/CPw4rPYLvKabxpF44rmJKWLI61xTB4FSA75L9FamuJKV73Ncoo0/c5qhxGNcsd2fe1gHTjg6CYGqP1Lg==, tarball: file:projects/task-resources.tgz} resolution: {integrity: sha512-zueI7N0xsHL7n4RRTJzNqXaDvrdC/BgotXDMVEFz4TKTvJuwGZ/39TfLaLQM0b/AWvDJV3iG3WS0z9ZMbtHc2g==, tarball: file:projects/task-resources.tgz}
id: file:projects/task-resources.tgz id: file:projects/task-resources.tgz
name: '@rush-temp/task-resources' name: '@rush-temp/task-resources'
version: 0.0.0 version: 0.0.0
@ -11091,7 +11182,7 @@ packages:
dev: false dev: false
file:projects/task.tgz: file:projects/task.tgz:
resolution: {integrity: sha512-yDiMMdXUoCo8/NLkpVdY8exQeuOaf18h+ICzhIEgyYjgEYmPxGCWVZ2qcOgWxEFJkEi6K7Gz5Fbz5wLpfVTD4g==, tarball: file:projects/task.tgz} resolution: {integrity: sha512-Yi88o15ExlXV9xqFXzpmi4I5OjnnY7l6SiQasIC7HqKc5/lG4KFvw/dlZHsFnEbRw3Zxa+laq9MejSMqLEzEVw==, tarball: file:projects/task.tgz}
name: '@rush-temp/task' name: '@rush-temp/task'
version: 0.0.0 version: 0.0.0
dependencies: dependencies:
@ -11111,7 +11202,7 @@ packages:
dev: false dev: false
file:projects/telegram-resources.tgz_476f694f64637160ae71e12ff57815b9: file:projects/telegram-resources.tgz_476f694f64637160ae71e12ff57815b9:
resolution: {integrity: sha512-k/x0wCwvORFOunkF3rKo5EFEPe7nWrKS75N1NBdm8owykYAie8gLNjOYcmupxe5k237nE7gEeVt4ak9lopwh6w==, tarball: file:projects/telegram-resources.tgz} resolution: {integrity: sha512-ZneaA8uvCmjuSf+zjIrPM1lzhi1At5Giud4UOzKwz2o0lrC4+npRTtCIZ52ZKjjNoOTmgf/hr9RYrqwCMH+z4g==, tarball: file:projects/telegram-resources.tgz}
id: file:projects/telegram-resources.tgz id: file:projects/telegram-resources.tgz
name: '@rush-temp/telegram-resources' name: '@rush-temp/telegram-resources'
version: 0.0.0 version: 0.0.0
@ -11242,7 +11333,7 @@ packages:
dev: false dev: false
file:projects/tool.tgz: file:projects/tool.tgz:
resolution: {integrity: sha512-M+CDNILEFBM+3jv4zU/2ImCQ0wcl2VfMRwI2Ls7ZhXko/+WN5VP4efG2LqK3aer/i3rpCr6gm+nDko7nWtwCZw==, tarball: file:projects/tool.tgz} resolution: {integrity: sha512-FFa7jbNSC9W0iRlRnNLYvlhWQUYLgCBbgIFsG9Bw0aWy6s8h1EGfJi5cC4b4z31MprdgXh9egR/cpi29fs7bHg==, tarball: file:projects/tool.tgz}
name: '@rush-temp/tool' name: '@rush-temp/tool'
version: 0.0.0 version: 0.0.0
dependencies: dependencies:
@ -11307,7 +11398,7 @@ packages:
dev: false dev: false
file:projects/upload.tgz: file:projects/upload.tgz:
resolution: {integrity: sha512-26Vcba+jRWoWVXgJQaT6vaY7fDTSgtyWj46y947mGWuyS4RtRbP1x43fw1hGV0RHNbZ9M6gvtLfVNy08DuYeFQ==, tarball: file:projects/upload.tgz} resolution: {integrity: sha512-WaGQUnqC0+TnVK024k91eTALA6ObkexINzJoxr5qZp5aPBJQ/UzP9Qyy2qcy5U7sFpUzUcADf25+r/LnYw1lfQ==, tarball: file:projects/upload.tgz}
name: '@rush-temp/upload' name: '@rush-temp/upload'
version: 0.0.0 version: 0.0.0
dependencies: dependencies:

View File

@ -80,6 +80,9 @@
"@anticrm/telegram-resources": "~0.6.0", "@anticrm/telegram-resources": "~0.6.0",
"@anticrm/devmodel": "~0.6.0", "@anticrm/devmodel": "~0.6.0",
"@anticrm/devmodel-resources": "~0.6.0", "@anticrm/devmodel-resources": "~0.6.0",
"@anticrm/workbench-assets": "~0.6.0" "@anticrm/workbench-assets": "~0.6.0",
"@anticrm/attachment": "~0.6.0",
"@anticrm/attachment-assets": "~0.6.0",
"@anticrm/attachment-resources": "~0.6.0"
} }
} }

View File

@ -25,12 +25,14 @@ import { recruitId } from '@anticrm/recruit'
import { activityId } from '@anticrm/activity' import { activityId } from '@anticrm/activity'
import { settingId } from '@anticrm/setting' import { settingId } from '@anticrm/setting'
import { telegramId } from '@anticrm/telegram' import { telegramId } from '@anticrm/telegram'
import { attachmentId } from '@anticrm/attachment'
import { clientId } from '@anticrm/client' import { clientId } from '@anticrm/client'
import '@anticrm/login-assets' import '@anticrm/login-assets'
import '@anticrm/task-assets' import '@anticrm/task-assets'
import '@anticrm/view-assets' import '@anticrm/view-assets'
import '@anticrm/chunter-assets' import '@anticrm/chunter-assets'
import '@anticrm/attachment-assets'
import '@anticrm/contact-assets' import '@anticrm/contact-assets'
import '@anticrm/recruit-assets' import '@anticrm/recruit-assets'
import '@anticrm/activity-assets' import '@anticrm/activity-assets'
@ -60,4 +62,5 @@ export function configurePlatform() {
addLocation(activityId, () => import(/*webpackChunkName: "activity" */ '@anticrm/activity-resources')) addLocation(activityId, () => import(/*webpackChunkName: "activity" */ '@anticrm/activity-resources'))
addLocation(settingId, () => import(/* webpackChunkName: "setting" */ '@anticrm/setting-resources')) addLocation(settingId, () => import(/* webpackChunkName: "setting" */ '@anticrm/setting-resources'))
addLocation(telegramId, () => import(/* webpackChunkName: "telegram" */ '@anticrm/telegram-resources')) addLocation(telegramId, () => import(/* webpackChunkName: "telegram" */ '@anticrm/telegram-resources'))
addLocation(attachmentId, () => import(/* webpackChunkName: "attachment" */ '@anticrm/attachment-resources'))
} }

View File

@ -43,6 +43,8 @@
"@anticrm/model-server-chunter": "~0.6.0", "@anticrm/model-server-chunter": "~0.6.0",
"@anticrm/model-server-recruit": "~0.6.0", "@anticrm/model-server-recruit": "~0.6.0",
"@anticrm/model-server-view": "~0.6.0", "@anticrm/model-server-view": "~0.6.0",
"@anticrm/model-activity": "~0.6.0" "@anticrm/model-activity": "~0.6.0",
"@anticrm/model-attachment": "~0.6.0"
} }
} }

View File

@ -24,6 +24,7 @@ import { createModel as chunterModel } from '@anticrm/model-chunter'
import { createModel as recruitModel } from '@anticrm/model-recruit' import { createModel as recruitModel } from '@anticrm/model-recruit'
import { createModel as settingModel } from '@anticrm/model-setting' import { createModel as settingModel } from '@anticrm/model-setting'
import { createModel as telegramModel } from '@anticrm/model-telegram' import { createModel as telegramModel } from '@anticrm/model-telegram'
import { createModel as attachmentModel } from '@anticrm/model-attachment'
import { createModel as serverCoreModel } from '@anticrm/model-server-core' import { createModel as serverCoreModel } from '@anticrm/model-server-core'
import { createModel as serverChunterModel } from '@anticrm/model-server-chunter' import { createModel as serverChunterModel } from '@anticrm/model-server-chunter'
@ -37,6 +38,7 @@ const builder = new Builder()
coreModel(builder) coreModel(builder)
activityModel(builder) activityModel(builder)
attachmentModel(builder)
viewModel(builder) viewModel(builder)
workbenchModel(builder) workbenchModel(builder)
contactModel(builder) contactModel(builder)

View File

@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@anticrm/model-rig/profiles/default/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}

View File

@ -0,0 +1,4 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/

View File

@ -0,0 +1,18 @@
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
/**
* (Required) The name of the rig package to inherit from.
* It should be an NPM package name with the "-rig" suffix.
*/
"rigPackageName": "@anticrm/model-rig"
/**
* (Optional) Selects a config profile from the rig package. The name must consist of
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
* If omitted, then the "default" profile will be used."
*/
// "rigProfile": "your-profile-name"
}

View File

@ -0,0 +1,38 @@
{
"name": "@anticrm/model-attachment",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},
"devDependencies": {
"@anticrm/model-rig": "~0.6.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-node": "^11.1.0",
"eslint": "^7.32.0",
"@types/heft-jest": "^1.0.2",
"@typescript-eslint/parser": "^5.4.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"prettier": "^2.4.1",
"@rushstack/heft": "^0.41.1"
},
"dependencies": {
"@anticrm/core": "~0.6.11",
"@anticrm/model": "~0.6.0",
"@anticrm/ui": "~0.6.0",
"@anticrm/attachment": "~0.6.0",
"@anticrm/attachment-resources": "~0.6.0",
"@anticrm/platform": "~0.6.5",
"@anticrm/model-core": "~0.6.0",
"@anticrm/model-view": "~0.6.0",
"@anticrm/activity": "~0.6.0"
}
}

View File

@ -0,0 +1,64 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import type { IntlString } from '@anticrm/platform'
import { Builder, Model, Prop, UX, TypeString, TypeTimestamp } from '@anticrm/model'
import type { Domain } from '@anticrm/core'
import core, { TAttachedDoc } from '@anticrm/model-core'
import type { Attachment } from '@anticrm/attachment'
import activity from '@anticrm/activity'
import view from '@anticrm/model-view'
import attachment from './plugin'
export const DOMAIN_ATTACHMENT = 'attachment' as Domain
@Model(attachment.class.Attachment, core.class.AttachedDoc, DOMAIN_ATTACHMENT)
@UX('File' as IntlString)
export class TAttachment extends TAttachedDoc implements Attachment {
@Prop(TypeString(), 'Name' as IntlString)
name!: string
@Prop(TypeString(), 'File' as IntlString)
file!: string
@Prop(TypeString(), 'Size' as IntlString)
size!: number
@Prop(TypeString(), 'Type' as IntlString)
type!: string
@Prop(TypeTimestamp(), 'Date' as IntlString)
lastModified!: number
}
export function createModel (builder: Builder): void {
builder.createModel(TAttachment)
builder.mixin(attachment.class.Attachment, core.class.Class, view.mixin.AttributePresenter, {
presenter: attachment.component.AttachmentPresenter
})
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
objectClass: attachment.class.Attachment,
icon: attachment.icon.Attachment,
txClass: core.class.TxCreateDoc,
component: attachment.activity.TxAttachmentCreate,
label: attachment.string.AddAttachment,
display: 'emphasized'
}, attachment.ids.TxAttachmentCreate)
}
export default attachment

View File

@ -0,0 +1,38 @@
//
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { attachmentId } from '@anticrm/attachment'
import attachment from '@anticrm/attachment-resources/src/plugin'
import type { IntlString } from '@anticrm/platform'
import { mergeIds } from '@anticrm/platform'
import type { Ref } from '@anticrm/core'
import type { AnyComponent } from '@anticrm/ui'
import type { TxViewlet } from '@anticrm/activity'
export default mergeIds(attachmentId, attachment, {
component: {
AttachmentsPresenter: '' as AnyComponent,
AttachmentPresenter: '' as AnyComponent
},
string: {
AddAttachment: '' as IntlString
},
ids: {
TxAttachmentCreate: '' as Ref<TxViewlet>
},
activity: {
TxAttachmentCreate: '' as AnyComponent
}
})

View File

@ -0,0 +1,8 @@
{
"extends": "./node_modules/@anticrm/model-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
}
}

View File

@ -34,6 +34,8 @@
"@anticrm/platform": "~0.6.5", "@anticrm/platform": "~0.6.5",
"@anticrm/model-core": "~0.6.0", "@anticrm/model-core": "~0.6.0",
"@anticrm/model-view": "~0.6.0", "@anticrm/model-view": "~0.6.0",
"@anticrm/model-attachment": "~0.6.0",
"@anticrm/attachment": "~0.6.0",
"@anticrm/model-workbench": "~0.6.1", "@anticrm/model-workbench": "~0.6.1",
"@anticrm/activity": "~0.6.0" "@anticrm/activity": "~0.6.0"
} }

View File

@ -14,13 +14,15 @@
// //
import type { IntlString } from '@anticrm/platform' import type { IntlString } from '@anticrm/platform'
import { Builder, Model, Prop, UX, TypeString, Index, TypeTimestamp } from '@anticrm/model' import { Builder, Model, Prop, UX, TypeString, Index } from '@anticrm/model'
import type { Ref, Doc, Class, Domain } from '@anticrm/core' import type { Ref, Doc, Class, Domain } from '@anticrm/core'
import { IndexKind } from '@anticrm/core' import { IndexKind } from '@anticrm/core'
import core, { TSpace, TDoc, TAttachedDoc } from '@anticrm/model-core' import core, { TSpace, TDoc, TAttachedDoc } from '@anticrm/model-core'
import type { Backlink, Channel, Message, Comment, Attachment } from '@anticrm/chunter' import type { Backlink, Channel, Message, Comment, Attachment } from '@anticrm/chunter'
import type { AnyComponent } from '@anticrm/ui' import type { AnyComponent } from '@anticrm/ui'
import activity from '@anticrm/activity' import activity from '@anticrm/activity'
import { TAttachment as TOriginAttachment } from '@anticrm/model-attachment'
import attachment from '@anticrm/attachment'
import workbench from '@anticrm/model-workbench' import workbench from '@anticrm/model-workbench'
@ -29,7 +31,6 @@ import chunter from './plugin'
export const DOMAIN_CHUNTER = 'chunter' as Domain export const DOMAIN_CHUNTER = 'chunter' as Domain
export const DOMAIN_COMMENT = 'comment' as Domain export const DOMAIN_COMMENT = 'comment' as Domain
export const DOMAIN_ATTACHMENT = 'attachment' as Domain
@Model(chunter.class.Channel, core.class.Space) @Model(chunter.class.Channel, core.class.Space)
@UX(chunter.string.Channel, chunter.icon.Hashtag) @UX(chunter.string.Channel, chunter.icon.Hashtag)
@ -50,33 +51,19 @@ export class TComment extends TAttachedDoc implements Comment {
message!: string message!: string
} }
@Model(chunter.class.Attachment, attachment.class.Attachment)
@UX('File' as IntlString)
export class TAttachment extends TOriginAttachment implements Attachment {
}
@Model(chunter.class.Backlink, chunter.class.Comment) @Model(chunter.class.Backlink, chunter.class.Comment)
export class TBacklink extends TComment implements Backlink { export class TBacklink extends TComment implements Backlink {
backlinkId!: Ref<Doc> backlinkId!: Ref<Doc>
backlinkClass!: Ref<Class<Doc>> backlinkClass!: Ref<Class<Doc>>
} }
@Model(chunter.class.Attachment, core.class.AttachedDoc, DOMAIN_ATTACHMENT)
@UX('File' as IntlString)
export class TAttachment extends TAttachedDoc implements Attachment {
@Prop(TypeString(), 'Name' as IntlString)
name!: string
@Prop(TypeString(), 'File' as IntlString)
file!: string
@Prop(TypeString(), 'Size' as IntlString)
size!: number
@Prop(TypeString(), 'Type' as IntlString)
type!: string
@Prop(TypeTimestamp(), 'Date' as IntlString)
lastModified!: number
}
export function createModel (builder: Builder): void { export function createModel (builder: Builder): void {
builder.createModel(TChannel, TMessage, TComment, TBacklink, TAttachment) builder.createModel(TChannel, TMessage, TComment, TBacklink)
builder.mixin(chunter.class.Channel, core.class.Class, workbench.mixin.SpaceView, { builder.mixin(chunter.class.Channel, core.class.Class, workbench.mixin.SpaceView, {
view: { view: {
class: chunter.class.Message class: chunter.class.Message
@ -124,10 +111,6 @@ export function createModel (builder: Builder): void {
members: [] members: []
}) })
builder.mixin(chunter.class.Attachment, core.class.Class, view.mixin.AttributePresenter, {
presenter: chunter.component.AttachmentPresenter
})
builder.mixin(chunter.class.Comment, core.class.Class, view.mixin.AttributePresenter, { builder.mixin(chunter.class.Comment, core.class.Class, view.mixin.AttributePresenter, {
presenter: chunter.component.CommentPresenter presenter: chunter.component.CommentPresenter
}) })
@ -151,15 +134,6 @@ export function createModel (builder: Builder): void {
display: 'inline', display: 'inline',
hideOnRemove: true hideOnRemove: true
}, chunter.ids.TxCommentRemove) }, chunter.ids.TxCommentRemove)
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
objectClass: chunter.class.Attachment,
icon: chunter.icon.Attachment,
txClass: core.class.TxCreateDoc,
component: chunter.activity.TxAttachmentCreate,
label: chunter.string.AddAttachment,
display: 'emphasized'
}, chunter.ids.TxAttachmentCreate)
} }
export default chunter export default chunter

View File

@ -24,26 +24,21 @@ import type { TxViewlet } from '@anticrm/activity'
export default mergeIds(chunterId, chunter, { export default mergeIds(chunterId, chunter, {
component: { component: {
AttachmentsPresenter: '' as AnyComponent,
AttachmentPresenter: '' as AnyComponent,
CommentsPresenter: '' as AnyComponent, CommentsPresenter: '' as AnyComponent,
CommentPresenter: '' as AnyComponent CommentPresenter: '' as AnyComponent
}, },
string: { string: {
ApplicationLabelChunter: '' as IntlString, ApplicationLabelChunter: '' as IntlString,
LeftComment: '' as IntlString, LeftComment: '' as IntlString
AddAttachment: '' as IntlString
}, },
viewlet: { viewlet: {
Chat: '' as Ref<ViewletDescriptor> Chat: '' as Ref<ViewletDescriptor>
}, },
ids: { ids: {
TxCommentCreate: '' as Ref<TxViewlet>, TxCommentCreate: '' as Ref<TxViewlet>,
TxCommentRemove: '' as Ref<TxViewlet>, TxCommentRemove: '' as Ref<TxViewlet>
TxAttachmentCreate: '' as Ref<TxViewlet>
}, },
activity: { activity: {
TxCommentCreate: '' as AnyComponent, TxCommentCreate: '' as AnyComponent
TxAttachmentCreate: '' as AnyComponent
} }
}) })

View File

@ -26,6 +26,8 @@
}, },
"dependencies": { "dependencies": {
"@anticrm/model-core": "~0.6.0", "@anticrm/model-core": "~0.6.0",
"@anticrm/model-workbench": "~0.6.0",
"@anticrm/model-attachment": "~0.6.0",
"@anticrm/model-view": "~0.6.0", "@anticrm/model-view": "~0.6.0",
"@anticrm/model": "~0.6.0", "@anticrm/model": "~0.6.0",
"@anticrm/core": "~0.6.11", "@anticrm/core": "~0.6.11",

View File

@ -18,10 +18,11 @@ import { DOMAIN_MODEL, IndexKind } from '@anticrm/core'
import { Builder, Model, Prop, TypeString, UX, Index } from '@anticrm/model' import { Builder, Model, Prop, TypeString, UX, Index } from '@anticrm/model'
import type { IntlString, Asset } from '@anticrm/platform' import type { IntlString, Asset } from '@anticrm/platform'
import core, { TAccount, TDoc, TType } from '@anticrm/model-core' import core, { TAccount, TDoc, TSpace, TType } from '@anticrm/model-core'
import type { Contact, Person, Organization, Employee, Channel, ChannelProvider, EmployeeAccount } from '@anticrm/contact' import type { Contact, Person, Persons, Organization, Organizations, Employee, Channel, ChannelProvider, EmployeeAccount } from '@anticrm/contact'
import workbench from '@anticrm/model-workbench'
import view from '@anticrm/model-view' import view from '@anticrm/model-view'
import attachment from '@anticrm/model-attachment'
import { ids as contact } from './plugin' import { ids as contact } from './plugin'
export const DOMAIN_CONTACT = 'contact' as Domain export const DOMAIN_CONTACT = 'contact' as Domain
@ -53,6 +54,12 @@ export class TContact extends TDoc implements Contact {
@Prop(TypeChannels(), 'Contact Info' as IntlString) @Prop(TypeChannels(), 'Contact Info' as IntlString)
channels!: Channel[] channels!: Channel[]
@Prop(TypeString(), 'Attachments' as IntlString)
attachments?: number
@Prop(TypeString(), 'Comments' as IntlString)
comments?: number
} }
@Model(contact.class.Person, contact.class.Contact) @Model(contact.class.Person, contact.class.Contact)
@ -63,6 +70,7 @@ export class TPerson extends TContact implements Person {
} }
@Model(contact.class.Organization, contact.class.Contact) @Model(contact.class.Organization, contact.class.Contact)
@UX('Organization' as IntlString)
export class TOrganization extends TContact implements Organization { export class TOrganization extends TContact implements Organization {
} }
@ -76,8 +84,89 @@ export class TEmployeeAccount extends TAccount implements EmployeeAccount {
name!: string name!: string
} }
@Model(contact.class.Organizations, core.class.Space)
@UX(contact.string.Organizations, contact.icon.Company)
export class TOrganizations extends TSpace implements Organizations {}
@Model(contact.class.Persons, core.class.Space)
@UX(contact.string.Persons, contact.icon.Person)
export class TPersons extends TSpace implements Persons {}
export function createModel (builder: Builder): void { export function createModel (builder: Builder): void {
builder.createModel(TChannelProvider, TTypeChannels, TContact, TPerson, TOrganization, TEmployee, TEmployeeAccount) builder.createModel(TChannelProvider, TTypeChannels, TContact, TPerson, TPersons, TOrganization, TOrganizations, TEmployee, TEmployeeAccount)
builder.mixin(contact.class.Persons, core.class.Class, workbench.mixin.SpaceView, {
view: {
class: contact.class.Person,
createItemDialog: contact.component.CreatePerson
}
})
builder.mixin(contact.class.Organizations, core.class.Class, workbench.mixin.SpaceView, {
view: {
class: contact.class.Organization,
createItemDialog: contact.component.CreateOrganization
}
})
builder.createDoc(workbench.class.Application, core.space.Model, {
label: contact.string.Contacts,
icon: contact.icon.Person,
hidden: false,
navigatorModel: {
spaces: [
{
label: contact.string.Persons,
spaceClass: contact.class.Persons,
addSpaceLabel: contact.string.CreatePersons,
createComponent: contact.component.CreatePersons
},
{
label: contact.string.Organizations,
spaceClass: contact.class.Organizations,
addSpaceLabel: contact.string.CreateOrganizations,
createComponent: contact.component.CreateOrganizations
}
]
}
})
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: contact.class.Person,
descriptor: view.viewlet.Table,
open: contact.component.EditPerson,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
options: { },
config: [
'',
'city',
{ presenter: attachment.component.AttachmentsPresenter, label: 'Files' },
'modifiedOn',
'channels'
]
})
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: contact.class.Organization,
descriptor: view.viewlet.Table,
open: contact.component.EditOrganization,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
options: { },
config: [
'',
{ presenter: attachment.component.AttachmentsPresenter, label: 'Files' },
'modifiedOn',
'channels'
]
})
builder.mixin(contact.class.Person, core.class.Class, view.mixin.ObjectEditor, {
editor: contact.component.EditPerson
})
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.ObjectEditor, {
editor: contact.component.EditOrganization
})
builder.mixin(contact.class.TypeChannels, core.class.Class, view.mixin.AttributePresenter, { builder.mixin(contact.class.TypeChannels, core.class.Class, view.mixin.AttributePresenter, {
presenter: contact.component.ChannelsPresenter presenter: contact.component.ChannelsPresenter
@ -123,6 +212,10 @@ export function createModel (builder: Builder): void {
builder.mixin(contact.class.Person, core.class.Class, view.mixin.AttributePresenter, { builder.mixin(contact.class.Person, core.class.Class, view.mixin.AttributePresenter, {
presenter: contact.component.PersonPresenter presenter: contact.component.PersonPresenter
}) })
builder.mixin(contact.class.Organization, core.class.Class, view.mixin.AttributePresenter, {
presenter: contact.component.OrganizationPresenter
})
} }
export { contact as default } export { contact as default }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
// //
import { mergeIds } from '@anticrm/platform' import { IntlString, mergeIds } from '@anticrm/platform'
import type { Ref, Class, Type } from '@anticrm/core' import type { Ref, Class, Type } from '@anticrm/core'
import contact, { contactId } from '@anticrm/contact' import contact, { contactId } from '@anticrm/contact'
import type { Channel } from '@anticrm/contact' import type { Channel } from '@anticrm/contact'
@ -23,7 +23,21 @@ import {} from '@anticrm/core'
export const ids = mergeIds(contactId, contact, { export const ids = mergeIds(contactId, contact, {
component: { component: {
PersonPresenter: '' as AnyComponent, PersonPresenter: '' as AnyComponent,
ChannelsPresenter: '' as AnyComponent ChannelsPresenter: '' as AnyComponent,
CreatePerson: '' as AnyComponent,
EditPerson: '' as AnyComponent,
EditOrganization: '' as AnyComponent,
CreateOrganization: '' as AnyComponent,
CreatePersons: '' as AnyComponent,
CreateOrganizations: '' as AnyComponent,
OrganizationPresenter: '' as AnyComponent
},
string: {
Organizations: '' as IntlString,
Persons: '' as IntlString,
Contacts: '' as IntlString,
CreatePersons: '' as IntlString,
CreateOrganizations: '' as IntlString
}, },
class: { class: {
TypeChannels: '' as Ref<Class<Type<Channel[]>>> TypeChannels: '' as Ref<Class<Type<Channel[]>>>

View File

@ -37,6 +37,7 @@
"@anticrm/recruit": "~0.6.0", "@anticrm/recruit": "~0.6.0",
"@anticrm/recruit-resources": "~0.6.0", "@anticrm/recruit-resources": "~0.6.0",
"@anticrm/chunter": "~0.6.0", "@anticrm/chunter": "~0.6.0",
"@anticrm/model-attachment": "~0.6.0",
"@anticrm/model-chunter": "~0.6.0", "@anticrm/model-chunter": "~0.6.0",
"@anticrm/view": "~0.6.0" "@anticrm/view": "~0.6.0"
} }

View File

@ -24,6 +24,7 @@ import workbench from '@anticrm/model-workbench'
import type { IntlString } from '@anticrm/platform' import type { IntlString } from '@anticrm/platform'
import type { Applicant, Candidate, Candidates, Vacancy } from '@anticrm/recruit' import type { Applicant, Candidate, Candidates, Vacancy } from '@anticrm/recruit'
import recruit from './plugin' import recruit from './plugin'
import attachment from '@anticrm/model-attachment'
export const DOMAIN_RECRUIT = 'recruit' as Domain export const DOMAIN_RECRUIT = 'recruit' as Domain
@ -42,7 +43,7 @@ export class TVacancy extends TSpaceWithStates implements Vacancy {
@Prop(TypeString(), 'Location' as IntlString, recruit.icon.Location) @Prop(TypeString(), 'Location' as IntlString, recruit.icon.Location)
location?: string location?: string
@Prop(TypeString(), 'Company' as IntlString, recruit.icon.Company) @Prop(TypeString(), 'Company' as IntlString, contact.icon.Company)
company?: string company?: string
} }
@ -157,7 +158,7 @@ export function createModel (builder: Builder): void {
'title', 'title',
'city', 'city',
{ presenter: recruit.component.ApplicationsPresenter, label: 'Apps' }, { presenter: recruit.component.ApplicationsPresenter, label: 'Apps' },
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' }, { presenter: attachment.component.AttachmentsPresenter, label: 'Files' },
{ presenter: chunter.component.CommentsPresenter, label: 'Comments' }, { presenter: chunter.component.CommentsPresenter, label: 'Comments' },
'modifiedOn', 'modifiedOn',
'channels' 'channels'
@ -180,7 +181,7 @@ export function createModel (builder: Builder): void {
'$lookup.attachedTo', '$lookup.attachedTo',
'$lookup.state', '$lookup.state',
'$lookup.attachedTo.city', '$lookup.attachedTo.city',
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' }, { presenter: attachment.component.AttachmentsPresenter, label: 'Files' },
{ presenter: chunter.component.CommentsPresenter, label: 'Comments' }, { presenter: chunter.component.CommentsPresenter, label: 'Comments' },
'modifiedOn', 'modifiedOn',
'$lookup.attachedTo.channels'] '$lookup.attachedTo.channels']

View File

@ -34,6 +34,7 @@
"@anticrm/model-view": "~0.6.0", "@anticrm/model-view": "~0.6.0",
"@anticrm/model-workbench": "~0.6.1", "@anticrm/model-workbench": "~0.6.1",
"@anticrm/model-contact": "~0.6.1", "@anticrm/model-contact": "~0.6.1",
"@anticrm/model-attachment": "~0.6.0",
"@anticrm/task": "~0.6.0", "@anticrm/task": "~0.6.0",
"@anticrm/model-chunter": "~0.6.0", "@anticrm/model-chunter": "~0.6.0",
"@anticrm/workbench": "~0.6.1" "@anticrm/workbench": "~0.6.1"

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
// //
import attachment from '@anticrm/model-attachment'
import type { Employee } from '@anticrm/contact' import type { Employee } from '@anticrm/contact'
import contact from '@anticrm/contact' import contact from '@anticrm/contact'
import type { Doc, DocWithState, Domain, FindOptions, Ref } from '@anticrm/core' import type { Doc, DocWithState, Domain, FindOptions, Ref } from '@anticrm/core'
@ -94,7 +95,7 @@ export function createModel (builder: Builder): void {
'', '',
'name', 'name',
'$lookup.assignee', '$lookup.assignee',
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' }, { presenter: attachment.component.AttachmentsPresenter, label: 'Files' },
{ presenter: chunter.component.CommentsPresenter, label: 'Comments' }, { presenter: chunter.component.CommentsPresenter, label: 'Comments' },
'modifiedOn' 'modifiedOn'
] ]

View File

@ -1,5 +1,6 @@
<!-- <!--
// Copyright © 2020 Anticrm Platform Contributors. // Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// //
// Licensed under the Eclipse Public License, Version 2.0 (the "License"); // Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may // you may not use this file except in compliance with the License. You may
@ -14,9 +15,8 @@
--> -->
<script lang="ts"> <script lang="ts">
import { CircleButton, Label } from '@anticrm/ui' import type { Doc } from '@anticrm/core'
import type { Ref, Class, Obj, Doc } from '@anticrm/core' import AttributeBarEditor from './AttributeBarEditor.svelte'
import { AttributeBarEditor } from '@anticrm/presentation'
export let object: Doc export let object: Doc
export let keys: string[] export let keys: string[]

View File

@ -20,8 +20,9 @@ export { default as UserBox } from './components/UserBox.svelte'
export { default as UserInfo } from './components/UserInfo.svelte' export { default as UserInfo } from './components/UserInfo.svelte'
export { default as Avatar } from './components/Avatar.svelte' export { default as Avatar } from './components/Avatar.svelte'
export { default as MessageViewer } from './components/MessageViewer.svelte' export { default as MessageViewer } from './components/MessageViewer.svelte'
export { default as AttributeEditor } from './components/AttributeEditor.svelte' export { default as AttributesBar } from './components/AttributesBar.svelte'
export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte' export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte'
export { default as AttributeEditor } from './components/AttributeEditor.svelte'
export { default as Card } from './components/Card.svelte' export { default as Card } from './components/Card.svelte'
export { default as Channels } from './components/Channels.svelte' export { default as Channels } from './components/Channels.svelte'
export { default as PDFViewer } from './components/PDFViewer.svelte' export { default as PDFViewer } from './components/PDFViewer.svelte'

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="chunter" viewBox="0 0 24 24">
<path d="M3,21.6c-0.2,0-0.3-0.1-0.4-0.2c-0.2-0.2-0.2-0.4-0.1-0.6l1.8-5.4c-0.6-1.2-0.8-2.5-0.8-3.8c0-3.4,1.9-6.5,4.9-8 c1.2-0.6,2.6-0.9,4-0.9h0.5c4.6,0.3,8.2,3.9,8.5,8.4l0,0.5c0,1.4-0.3,2.8-0.9,4c-1.5,3-4.6,4.9-8,4.9c0,0,0,0,0,0 c-1.3,0-2.6-0.3-3.8-0.8l-5.4,1.8C3.1,21.6,3.1,21.6,3,21.6z M12.3,3.9c-1.2,0-2.4,0.3-3.4,0.8c-2.6,1.3-4.3,4-4.3,6.9 c0,1.2,0.3,2.4,0.8,3.5c0.1,0.1,0.1,0.3,0,0.5l-1.5,4.5l4.5-1.5c0.2-0.1,0.3,0,0.5,0c1.1,0.5,2.2,0.8,3.5,0.8c3,0,5.6-1.6,6.9-4.3 c0.5-1.1,0.8-2.3,0.8-3.5c0,0,0,0,0,0v-0.5c-0.2-3.9-3.4-7-7.3-7.3L12.3,3.9C12.3,3.9,12.3,3.9,12.3,3.9z M21.3,11.7L21.3,11.7 L21.3,11.7z"/>
</symbol>
<symbol id="hashtag" viewBox="0 0 16 16">
<path d="M14,9.6h-3.2l0.4-3.2H14c0.3,0,0.6-0.3,0.6-0.6S14.3,5.2,14,5.2h-2.7l0.4-3.7c0-0.3-0.2-0.6-0.5-0.7 c-0.3,0-0.6,0.2-0.7,0.5l-0.4,3.8H6.9l0.4-3.7c0-0.3-0.2-0.6-0.5-0.7c-0.3,0-0.6,0.2-0.7,0.5L5.7,5.2H2.3C2,5.2,1.7,5.5,1.7,5.8 S2,6.4,2.3,6.4h3.2L5.2,9.6H2.3c-0.3,0-0.6,0.3-0.6,0.6s0.3,0.6,0.6,0.6h2.7l-0.4,3.7c0,0.3,0.2,0.6,0.5,0.7c0,0,0,0,0.1,0 c0.3,0,0.6-0.2,0.6-0.5l0.4-3.8h3.2L9,14.5c0,0.3,0.2,0.6,0.5,0.7c0,0,0,0,0.1,0c0.3,0,0.6-0.2,0.6-0.5l0.4-3.8H14 c0.3,0,0.6-0.3,0.6-0.6S14.3,9.6,14,9.6z M6.4,9.6l0.4-3.2h3.2L9.6,9.6H6.4z"/>
</symbol>
<symbol id="lock" viewBox="0 0 16 16">
<path d="M13,6.9h-1.1V4.8c0-2.2-1.8-3.9-3.9-3.9c-2.2,0-3.9,1.8-3.9,3.9v2.1H3c-0.9,0-1.6,0.7-1.6,1.6v5.3 c0,0.9,0.7,1.6,1.6,1.6h10c0.9,0,1.6-0.7,1.6-1.6V8.5C14.6,7.6,13.9,6.9,13,6.9z M5.3,4.8c0-1.5,1.2-2.7,2.7-2.7s2.7,1.2,2.7,2.7 v2.1H5.3V4.8z M13.4,13.8c0,0.2-0.2,0.4-0.4,0.4H3c-0.2,0-0.4-0.2-0.4-0.4V8.5c0-0.2,0.2-0.4,0.4-0.4h10c0.2,0,0.4,0.2,0.4,0.4V13.8 z"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,7 @@
{
"string": {
"UploadDropFilesHere": "Upload or drop files here",
"NoAttachments": "There are no attachments",
"AddAttachment": "uploaded an attachment"
}
}

View File

@ -0,0 +1,19 @@
{
"name": "@anticrm/attachment-assets",
"version": "0.6.0",
"main": "src/index.ts",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "",
"build:docs": "api-extractor run --local",
"lint": "ts-standard src",
"lint:fix": "ts-standard --fix src",
"format": "prettier --write 'src/**/*.{ts*,js*,yml}' && ts-standard --fix src"
},
"devDependencies": {},
"dependencies": {
"@anticrm/platform": "~0.6.5",
"@anticrm/attachment": "~0.6.0"
}
}

View File

@ -0,0 +1,24 @@
//
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { addStringsLoader, loadMetadata } from '@anticrm/platform'
import attachment, { attachmentId } from '@anticrm/attachment'
const icons = require('../assets/icons.svg')
loadMetadata(attachment.icon, {
Attachment: `${icons}#chunter`
})
addStringsLoader(attachmentId, async (lang: string) => await import(`../lang/${lang}.json`))

View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "esnext",
"module": "esnext",
"declaration": true,
"outDir": "./lib",
"strict": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
]
}
}

View File

@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@anticrm/platform-rig/profiles/ui/config/eslint.config.json'],
parserOptions: { tsconfigRootDir: __dirname },
settings: {
'svelte3/ignore-styles': () => true
}
}

View File

@ -0,0 +1,45 @@
{
"name": "@anticrm/attachment-resources",
"version": "0.6.0",
"main": "src/index.ts",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "echo 'no build for ui'",
"build:docs": "api-extractor run --local",
"lint": "svelte-check && eslint",
"lint:fix": "eslint --fix src",
"format": "prettier --write --plugin-search-dir=. src && eslint --fix src"
},
"devDependencies": {
"svelte-loader": "^3.1.2",
"sass": "^1.37.5",
"svelte-preprocess": "^4.7.4",
"@anticrm/platform-rig": "~0.6.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-svelte3": "~3.2.1",
"prettier-plugin-svelte": "^2.2.0",
"eslint": "^7.32.0",
"prettier": "^2.4.1",
"svelte-check": "^2.2.10",
"typescript": "^4.3.5"
},
"dependencies": {
"@anticrm/platform": "~0.6.5",
"svelte": "^3.37.0",
"@anticrm/ui": "~0.6.0",
"@anticrm/presentation": "~0.6.2",
"@anticrm/attachment": "~0.6.0",
"@anticrm/core": "~0.6.11",
"@anticrm/view": "~0.6.0",
"@anticrm/view-resources": "~0.6.0",
"@anticrm/panel": "~0.6.0",
"@anticrm/login": "~0.6.1",
"filesize": "^8.0.3"
}
}

View File

@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('autoprefixer')
]
}

View File

@ -18,14 +18,14 @@
import type { Ref, Doc } from '@anticrm/core' import type { Ref, Doc } from '@anticrm/core'
import { Table } from '@anticrm/view-resources' import { Table } from '@anticrm/view-resources'
import chunter from '@anticrm/chunter' import attachment from '@anticrm/attachment'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
</script> </script>
<Table <Table
_class={chunter.class.Attachment} _class={attachment.class.Attachment}
config={['', 'lastModified']} config={['', 'lastModified']}
options={ {} } options={ {} }
query={ { attachedTo: objectId } } query={ { attachedTo: objectId } }

View File

@ -15,7 +15,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import type { Attachment } from '@anticrm/chunter' import type { Attachment } from '@anticrm/attachment'
import { showPopup, closeTooltip } from '@anticrm/ui' import { showPopup, closeTooltip } from '@anticrm/ui'
import { PDFViewer, getFileUrl } from '@anticrm/presentation' import { PDFViewer, getFileUrl } from '@anticrm/presentation'
import filesize from 'filesize' import filesize from 'filesize'

View File

@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import type { Attachment } from '@anticrm/chunter' import attachment from '../plugin'
import chunter from '@anticrm/chunter' import type { Attachment } from '@anticrm/attachment'
import type { Class, Doc, Ref, Space } from '@anticrm/core' import type { Class, Doc, Ref, Space } from '@anticrm/core'
import { setPlatformStatus, unknownError } from '@anticrm/platform' import { setPlatformStatus, unknownError } from '@anticrm/platform'
import { createQuery, getClient } from '@anticrm/presentation' import { createQuery, getClient } from '@anticrm/presentation'
@ -22,16 +22,16 @@
import { Table } from '@anticrm/view-resources' import { Table } from '@anticrm/view-resources'
import { uploadFile } from '../utils' import { uploadFile } from '../utils'
import UploadDuo from './icons/UploadDuo.svelte' import UploadDuo from './icons/UploadDuo.svelte'
import task from '../plugin'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
export let space: Ref<Space> export let space: Ref<Space>
export let _class: Ref<Class<Doc>> export let _class: Ref<Class<Doc>>
export let noLabel: IntlString = attachment.string.NoAttachments
let attachments: Attachment[] = [] let attachments: Attachment[] = []
const query = createQuery() const query = createQuery()
$: query.query(chunter.class.Attachment, { attachedTo: objectId }, (result) => { $: query.query(attachment.class.Attachment, { attachedTo: objectId }, (result) => {
attachments = result attachments = result
}) })
@ -45,7 +45,7 @@
try { try {
const uuid = await uploadFile(space, file, objectId) const uuid = await uploadFile(space, file, objectId)
console.log('uploaded file uuid', uuid) console.log('uploaded file uuid', uuid)
client.addCollection(chunter.class.Attachment, space, objectId, _class, 'attachments', { client.addCollection(attachment.class.Attachment, space, objectId, _class, 'attachments', {
name: file.name, name: file.name,
file: uuid, file: uuid,
type: file.type, type: file.type,
@ -60,7 +60,6 @@
} }
function fileSelected () { function fileSelected () {
console.log(inputFile.files)
const list = inputFile.files const list = inputFile.files
if (list === null || list.length === 0) return if (list === null || list.length === 0) return
for (let index = 0; index < list.length; index++) { for (let index = 0; index < list.length; index++) {
@ -120,15 +119,15 @@
> >
<UploadDuo size={'large'} /> <UploadDuo size={'large'} />
<div class="small-text content-dark-color mt-2"> <div class="small-text content-dark-color mt-2">
<Label label={task.string.NoAttachmentsForTask} /> <Label label={noLabel} />
</div> </div>
<div class="small-text"> <div class="small-text">
<a href={'#'} on:click={() => inputFile.click()}><Label label={task.string.UploadDropFilesHere} /></a> <a href={'#'} on:click={() => inputFile.click()}><Label label={attachment.string.UploadDropFilesHere} /></a>
</div> </div>
</div> </div>
{:else} {:else}
<Table <Table
_class={chunter.class.Attachment} _class={attachment.class.Attachment}
config={['', 'lastModified']} config={['', 'lastModified']}
options={{}} options={{}}
query={{ attachedTo: objectId }} query={{ attachedTo: objectId }}

View File

@ -16,23 +16,13 @@
<script lang="ts"> <script lang="ts">
import type { Doc } from '@anticrm/core' import type { Doc } from '@anticrm/core'
import type { Attachment } from '@anticrm/chunter' import { Tooltip, IconAttachment } from '@anticrm/ui'
import { IconFile, Link, Tooltip, IconAttachment } from '@anticrm/ui'
import { PDFViewer } from '@anticrm/presentation'
import AttachmentPopup from './AttachmentPopup.svelte' import AttachmentPopup from './AttachmentPopup.svelte'
export let value: Doc & { attachments?: number } export let value: Doc & { attachments?: number }
</script> </script>
<!-- {#if Object.keys(value.attachments).length === 1}
<Link label={Object.values(value.attachments)[0].name} href={'#'} icon={IconFile} on:click={ () => { showPopup(PDFViewer, { file: Object.values(value.attachments)[0].file }, 'right') } }/>
{:else if Object.keys(value.attachments).length > 1}
<Tooltip label={'Attachments (' + Object.values(value.attachments).length + ')'} component={AttachmentPopup} props={{ files: value.attachments }}>
<Link label={Object.values(value.attachments).length + ' files'} href={'#'} icon={IconFile} />
</Tooltip>
{/if} -->
{#if value.attachments && value.attachments > 0} {#if value.attachments && value.attachments > 0}
<Tooltip label={'Attachments (' + value.attachments + ')'} component={AttachmentPopup} props={{ objectId: value._id }}> <Tooltip label={'Attachments (' + value.attachments + ')'} component={AttachmentPopup} props={{ objectId: value._id }}>
<div class="sm-tool-icon"> <div class="sm-tool-icon">

View File

@ -14,10 +14,10 @@
--> -->
<script lang="ts"> <script lang="ts">
import type { Attachment } from "@anticrm/chunter"; import type { Attachment } from "@anticrm/attachment"
import type { TxCreateDoc } from "@anticrm/core"; import type { TxCreateDoc } from "@anticrm/core"
import { TxProcessor } from '@anticrm/core'; import { TxProcessor } from '@anticrm/core'
import AttachmentPresenter from "../AttachmentPresenter.svelte"; import AttachmentPresenter from "../AttachmentPresenter.svelte"
export let tx: TxCreateDoc<Attachment> export let tx: TxCreateDoc<Attachment>
</script> </script>

View File

@ -0,0 +1,32 @@
//
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import AttachmentsPresenter from './components/AttachmentsPresenter.svelte'
import AttachmentPresenter from './components/AttachmentPresenter.svelte'
import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
import Attachments from './components/Attachments.svelte'
export { AttachmentsPresenter }
export default async () => ({
component: {
AttachmentsPresenter,
AttachmentPresenter,
Attachments
},
activity: {
TxAttachmentCreate
}
})

View File

@ -0,0 +1,26 @@
//
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { mergeIds } from '@anticrm/platform'
import type { IntlString } from '@anticrm/platform'
import attachment, { attachmentId } from '@anticrm/attachment'
export default mergeIds(attachmentId, attachment, {
string: {
NoAttachments: '' as IntlString,
UploadDropFilesHere: '' as IntlString
}
})

View File

@ -14,12 +14,9 @@
// limitations under the License. // limitations under the License.
// //
import type { Class, Data, Doc, Ref, Space, State } from '@anticrm/core' import type { Doc, Ref, Space } from '@anticrm/core'
import login from '@anticrm/login' import login from '@anticrm/login'
import { getMetadata } from '@anticrm/platform' import { getMetadata } from '@anticrm/platform'
import { Project } from '@anticrm/task'
import core from '@anticrm/core'
import view, { Kanban } from '@anticrm/view'
export async function uploadFile (space: Ref<Space>, file: File, attachedTo: Ref<Doc>): Promise<string> { export async function uploadFile (space: Ref<Space>, file: File, attachedTo: Ref<Doc>): Promise<string> {
console.log(file) console.log(file)

View File

@ -0,0 +1,5 @@
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
preprocess: sveltePreprocess()
};

View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "esnext",
"module": "esnext",
"declaration": true,
"outDir": "./lib",
"strict": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
]
}
}

View File

@ -0,0 +1,7 @@
module.exports = {
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}

View File

@ -0,0 +1,4 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/

View File

@ -0,0 +1,18 @@
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
/**
* (Required) The name of the rig package to inherit from.
* It should be an NPM package name with the "-rig" suffix.
*/
"rigPackageName": "@anticrm/platform-rig"
/**
* (Optional) Selects a config profile from the rig package. The name must consist of
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
* If omitted, then the "default" profile will be used."
*/
// "rigProfile": "your-profile-name"
}

View File

@ -0,0 +1,33 @@
{
"name": "@anticrm/attachment",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},
"devDependencies": {
"@anticrm/platform-rig": "~0.6.0",
"@types/heft-jest": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-node": "^11.1.0",
"eslint": "^7.32.0",
"@typescript-eslint/parser": "^5.4.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"prettier": "^2.4.1",
"@rushstack/heft": "^0.41.1",
"typescript": "^4.3.5"
},
"dependencies": {
"@anticrm/platform": "~0.6.5",
"@anticrm/ui": "~0.6.0",
"@anticrm/core": "~0.6.11"
}
}

View File

@ -1,4 +1,4 @@
<!-- //
// Copyright © 2020, 2021 Anticrm Platform Contributors. // Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc. // Copyright © 2021 Hardcore Engineering Inc.
// //
@ -12,13 +12,37 @@
// //
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
--> //
<script lang="ts"> import type { Ref, Class, AttachedDoc } from '@anticrm/core'
export let size: 'small' | 'medium' | 'large' import { plugin } from '@anticrm/platform'
const fill: string = 'var(--theme-caption-color)' import type { Asset, Plugin } from '@anticrm/platform'
</script> import { AnyComponent } from '@anticrm/ui'
<svg class="svg-{size}" {fill} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> /**
<path d="M12.9,2.7H3.1c-1,0-1.7,0.8-1.7,1.7v7.5c0,1,0.8,1.7,1.7,1.7h9.9c1,0,1.7-0.8,1.7-1.7V4.4C14.7,3.5,13.9,2.7,12.9,2.7z M12.9,3.7c0.1,0,0.2,0,0.3,0.1L8,7.9L2.8,3.8c0.1,0,0.2-0.1,0.3-0.1H12.9z M12.9,12.6H3.1c-0.4,0-0.7-0.3-0.7-0.7V4.7L7.7,9 C7.8,9,7.9,9.1,8,9.1S8.2,9,8.3,9l5.4-4.3v7.2C13.7,12.3,13.3,12.6,12.9,12.6z"/> * @public
</svg> */
export interface Attachment extends AttachedDoc {
name: string
file: string
size: number
type: string
lastModified: number
}
/**
* @public
*/
export const attachmentId = 'attachment' as Plugin
export default plugin(attachmentId, {
component: {
Attachments: '' as AnyComponent
},
icon: {
Attachment: '' as Asset
},
class: {
Attachment: '' as Ref<Class<Attachment>>
}
})

View File

@ -0,0 +1,9 @@
{
"extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"lib": ["esnext", "dom"]
}
}

View File

@ -20,8 +20,7 @@ const icons = require('../assets/icons.svg')
loadMetadata(chunter.icon, { loadMetadata(chunter.icon, {
Chunter: `${icons}#chunter`, Chunter: `${icons}#chunter`,
Hashtag: `${icons}#hashtag`, Hashtag: `${icons}#hashtag`,
Lock: `${icons}#lock`, Lock: `${icons}#lock`
Attachment: `${icons}#chunter`
}) })
addStringsLoader(chunterId, async (lang: string) => await import(`../lang/${lang}.json`)) addStringsLoader(chunterId, async (lang: string) => await import(`../lang/${lang}.json`))

View File

@ -38,7 +38,6 @@
"svelte": "^3.37.0", "svelte": "^3.37.0",
"@anticrm/text-editor": "~0.6.0", "@anticrm/text-editor": "~0.6.0",
"@anticrm/contact": "~0.6.2", "@anticrm/contact": "~0.6.2",
"@anticrm/view-resources": "~0.6.0", "@anticrm/view-resources": "~0.6.0"
"filesize": "^8.0.3"
} }
} }

View File

@ -1,84 +0,0 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import type { Bag } from '@anticrm/core'
import type { Attachment } from '@anticrm/chunter'
import { IconFile, Link, showPopup } from '@anticrm/ui'
import { PDFViewer } from '@anticrm/presentation'
export let files: Bag<Attachment>
</script>
<div class="files-container">
<span class="icon"><IconFile size={'small'}/></span>
{Object.values(files).length} files
<div class="window">
{#each Object.values(files) as file}
<div class="flex-row-center file">
<Link label={file.name} href={'#'} icon={IconFile} on:click={ () => { showPopup(PDFViewer, { file: file.file }, 'right') } }/>
</div>
{/each}
</div>
</div>
<style lang="scss">
.files-container {
position: relative;
display: flex;
align-items: center;
color: var(--theme-content-color);
cursor: pointer;
.icon {
margin-right: .25rem;
transform-origin: center center;
transform: scale(.75);
opacity: .6;
}
&:hover {
color: var(--theme-caption-color);
.icon { opacity: 1; }
.window { visibility: visible; }
&::after { content: ''; }
}
&::after {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: -1rem;
}
.window {
visibility: hidden;
position: absolute;
display: flex;
flex-direction: column;
padding: 1.25rem 1.5rem;
top: 1.5rem;
left: 0;
min-width: 100%;
background-color: var(--theme-button-bg-focused);
border: 1px solid var(--theme-button-border-enabled);
border-radius: .75rem;
box-shadow: 0 .75rem 1.25rem rgba(0, 0, 0, .2);
z-index: 1;
.file + .file { margin-top: .25rem; }
}
}
</style>

View File

@ -15,26 +15,20 @@
import CreateChannel from './components/CreateChannel.svelte' import CreateChannel from './components/CreateChannel.svelte'
import ChannelView from './components/ChannelView.svelte' import ChannelView from './components/ChannelView.svelte'
import AttachmentsPresenter from './components/AttachmentsPresenter.svelte'
import AttachmentPresenter from './components/AttachmentPresenter.svelte'
import CommentPresenter from './components/CommentPresenter.svelte' import CommentPresenter from './components/CommentPresenter.svelte'
import CommentsPresenter from './components/CommentsPresenter.svelte' import CommentsPresenter from './components/CommentsPresenter.svelte'
import TxCommentCreate from './components/activity/TxCommentCreate.svelte' import TxCommentCreate from './components/activity/TxCommentCreate.svelte'
import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
export { AttachmentsPresenter, CommentsPresenter } export { CommentsPresenter }
export default async () => ({ export default async () => ({
component: { component: {
CreateChannel, CreateChannel,
ChannelView, ChannelView,
AttachmentsPresenter,
AttachmentPresenter,
CommentPresenter, CommentPresenter,
CommentsPresenter CommentsPresenter
}, },
activity: { activity: {
TxCommentCreate, TxCommentCreate
TxAttachmentCreate
} }
}) })

View File

@ -26,6 +26,7 @@
"typescript": "^4.3.5" "typescript": "^4.3.5"
}, },
"dependencies": { "dependencies": {
"@anticrm/attachment": "~0.6.0",
"@anticrm/platform": "~0.6.5", "@anticrm/platform": "~0.6.5",
"@anticrm/core": "~0.6.11" "@anticrm/core": "~0.6.11"
} }

View File

@ -16,6 +16,7 @@
import { IntlString, plugin } from '@anticrm/platform' import { IntlString, plugin } from '@anticrm/platform'
import type { Asset, Plugin } from '@anticrm/platform' import type { Asset, Plugin } from '@anticrm/platform'
import type { Space, Doc, Ref, Class, AttachedDoc } from '@anticrm/core' import type { Space, Doc, Ref, Class, AttachedDoc } from '@anticrm/core'
import type { Attachment as OriginAttachment } from '@anticrm/attachment'
/** /**
* @public * @public
@ -47,13 +48,7 @@ export interface Backlink extends Comment {
/** /**
* @public * @public
*/ */
export interface Attachment extends AttachedDoc { export interface Attachment extends OriginAttachment {}
name: string
file: string
size: number
type: string
lastModified: number
}
/** /**
* @public * @public
@ -64,8 +59,7 @@ export default plugin(chunterId, {
icon: { icon: {
Chunter: '' as Asset, Chunter: '' as Asset,
Hashtag: '' as Asset, Hashtag: '' as Asset,
Lock: '' as Asset, Lock: '' as Asset
Attachment: '' as Asset
}, },
class: { class: {
Message: '' as Ref<Class<Message>>, Message: '' as Ref<Class<Message>>,

View File

@ -40,4 +40,12 @@
<symbol id="github" viewBox="0 0 16 16"> <symbol id="github" viewBox="0 0 16 16">
<path d="M16,8c0-4.4-3.6-8-8-8S0,3.6,0,8c0,3.5,2.3,6.5,5.3,7.6c0.1-0.1,0.4-0.3,0.4-0.5c0-0.4,0-1.6,0-1.6 s-0.4,0-0.8,0c-1.2,0-1.6-0.8-1.9-1.2c-0.3-0.5-0.5-0.8-0.9-1.1c-0.3-0.1-0.3-0.3,0-0.4c1.1-0.3,1.3,1.2,2.1,1.5 c0.5,0.1,1.2,0.1,1.6-0.1c0-0.4,0.4-0.8,0.7-1.1c-1.9-0.1-2.9-0.8-3.6-1.9V9.1L2.8,8.8V8.7C2.5,8.1,2.4,7.5,2.4,6.8 c0-1.2,0.4-1.6,0.9-2.3C2.9,3.2,3.5,2.3,3.5,2.3s0.8-0.1,2.4,0.9c0.8-0.4,2.9-0.4,4-0.1c0.7-0.4,1.9-1.1,2.3-0.8 c0.1,0.3,0.4,0.8,0.1,2.1c0.1,0.3,1.1,0.9,1.1,2.7c0,0.7-0.1,1.2-0.3,1.6l-0.1,0.3c0,0,0,0.1-0.1,0.3v0.1c-0.5,1.2-1.7,1.7-3.6,1.9 C9.7,11.6,10,12,10,13.3s0,1.5,0,1.7s0.3,0.4,0.4,0.5C13.7,14.4,16,11.5,16,8z"/> <path d="M16,8c0-4.4-3.6-8-8-8S0,3.6,0,8c0,3.5,2.3,6.5,5.3,7.6c0.1-0.1,0.4-0.3,0.4-0.5c0-0.4,0-1.6,0-1.6 s-0.4,0-0.8,0c-1.2,0-1.6-0.8-1.9-1.2c-0.3-0.5-0.5-0.8-0.9-1.1c-0.3-0.1-0.3-0.3,0-0.4c1.1-0.3,1.3,1.2,2.1,1.5 c0.5,0.1,1.2,0.1,1.6-0.1c0-0.4,0.4-0.8,0.7-1.1c-1.9-0.1-2.9-0.8-3.6-1.9V9.1L2.8,8.8V8.7C2.5,8.1,2.4,7.5,2.4,6.8 c0-1.2,0.4-1.6,0.9-2.3C2.9,3.2,3.5,2.3,3.5,2.3s0.8-0.1,2.4,0.9c0.8-0.4,2.9-0.4,4-0.1c0.7-0.4,1.9-1.1,2.3-0.8 c0.1,0.3,0.4,0.8,0.1,2.1c0.1,0.3,1.1,0.9,1.1,2.7c0,0.7-0.1,1.2-0.3,1.6l-0.1,0.3c0,0,0,0.1-0.1,0.3v0.1c-0.5,1.2-1.7,1.7-3.6,1.9 C9.7,11.6,10,12,10,13.3s0,1.5,0,1.7s0.3,0.4,0.4,0.5C13.7,14.4,16,11.5,16,8z"/>
</symbol> </symbol>
<symbol id="company" viewBox="0 0 16 16">
<path d="M15.3,14.7h-0.7V4c0-0.3-0.2-0.6-0.5-0.6l-7.3-2c-0.2-0.1-0.4,0-0.6,0.1C6.1,1.6,6,1.8,6,2v3.3H2 C1.6,5.3,1.3,5.6,1.3,6v8.7H0.7C0.3,14.7,0,15,0,15.3C0,15.7,0.3,16,0.7,16h14.7c0.4,0,0.7-0.3,0.7-0.7C16,15,15.7,14.7,15.3,14.7z M2.7,14.7v-8h6v8H2.7z M9.3,5.3h-2V2.9l6,1.6v10.2H10V6C10,5.6,9.7,5.3,9.3,5.3z"/>
</symbol>
<symbol id="person" viewBox="0 0 24 24">
<path d="M12.1,11.7c2.1,0,3.8-1.7,3.8-3.8s-1.7-3.8-3.8-3.8S8.4,5.8,8.4,7.9S10.1,11.7,12.1,11.7z M12.1,5.5 c1.3,0,2.3,1.1,2.3,2.3s-1.1,2.3-2.3,2.3S9.8,9.2,9.8,7.9S10.8,5.5,12.1,5.5z"/>
<path d="M12,0C5.4,0,0,5.4,0,12c0,6.6,5.4,12,12,12c6.6,0,12-5.4,12-12C24,5.4,18.6,0,12,0z M12,22.6 C6.2,22.6,1.4,17.8,1.4,12C1.4,6.2,6.2,1.4,12,1.4c5.8,0,10.6,4.7,10.6,10.6C22.6,17.8,17.8,22.6,12,22.6z"/>
<path d="M18.6,16.2c-0.3-0.9-0.8-1.6-1.5-2.2c-0.9-0.7-2-1.1-3.1-1.1h-1.5h-0.9h-1.5c-1.1,0-2.2,0.4-3.1,1.1 c-0.7,0.6-1.2,1.3-1.5,2.2l-0.2,0.6c-0.1,0.4,0.1,0.8,0.5,0.9c0.1,0,0.1,0,0.2,0c0.3,0,0.6-0.2,0.7-0.5L7,16.7 c0.2-0.6,0.5-1.1,1-1.5c0.6-0.5,1.4-0.8,2.2-0.8h1.5h0.9h1.5c0.8,0,1.6,0.3,2.2,0.8c0.5,0.4,0.8,0.9,1,1.5l0.2,0.6 c0.1,0.3,0.4,0.5,0.7,0.5c0.1,0,0.1,0,0.2,0c0.4-0.1,0.6-0.5,0.5-0.9L18.6,16.2z"/>
</symbol>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -0,0 +1,18 @@
{
"string": {
"Apply": "Apply",
"Contacts": "Contacts",
"Persons": "Persons",
"Organizations": "Organizations",
"CreatePerson": "Create person",
"CreatePersons": "Create persons folder",
"CreateOrganizations": "Create organizations folder",
"Name": "Name",
"SelectFolder": "Select folder",
"OrganizationsFolder": "Organizations folder",
"PersonsFolder": "Persons folder",
"AddSocialLinks": "Add social links",
"MakePrivate": "Make private",
"MakePrivateDescription": "Only members can see it"
}
}

View File

@ -13,11 +13,11 @@
// limitations under the License. // limitations under the License.
// //
import { loadMetadata } from '@anticrm/platform' import { addStringsLoader, loadMetadata } from '@anticrm/platform'
import chunter from '@anticrm/contact' import contact, { contactId } from '@anticrm/contact'
const icons = require('../assets/icons.svg') const icons = require('../assets/icons.svg')
loadMetadata(chunter.icon, { loadMetadata(contact.icon, {
Phone: `${icons}#phone`, Phone: `${icons}#phone`,
Email: `${icons}#email`, Email: `${icons}#email`,
Discord: `${icons}#discord`, Discord: `${icons}#discord`,
@ -29,5 +29,9 @@ loadMetadata(chunter.icon, {
VK: `${icons}#vk`, VK: `${icons}#vk`,
WhatsApp: `${icons}#whatsapp`, WhatsApp: `${icons}#whatsapp`,
Youtube: `${icons}#youtube`, Youtube: `${icons}#youtube`,
GitHub: `${icons}#github` GitHub: `${icons}#github`,
Person: `${icons}#person`,
Company: `${icons}#company`
}) })
addStringsLoader(contactId, async (lang: string) => await import(`../lang/${lang}.json`))

View File

@ -36,6 +36,8 @@
"@anticrm/ui": "~0.6.0", "@anticrm/ui": "~0.6.0",
"@anticrm/presentation": "~0.6.2", "@anticrm/presentation": "~0.6.2",
"@anticrm/core": "~0.6.11", "@anticrm/core": "~0.6.11",
"@anticrm/view": "~0.6.0" "@anticrm/view": "~0.6.0",
"@anticrm/attachment": "~0.6.0",
"@anticrm/panel": "~0.6.0"
} }
} }

View File

@ -0,0 +1,95 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref, Space } from '@anticrm/core'
import { getClient, Card, Channels, Avatar } from '@anticrm/presentation'
import { EditBox, showPopup, CircleButton, IconEdit, IconAdd, Label } from '@anticrm/ui'
import SocialEditor from './SocialEditor.svelte'
import { Organization } from '@anticrm/contact'
import contact from '../plugin'
import Company from './icons/Company.svelte'
export let space: Ref<Space>
let _space = space
export function canClose(): boolean {
return object.name === ''
}
const object: Organization = {
name: ''
} as Organization
const dispatch = createEventDispatcher()
const client = getClient()
async function createOrganization() {
await client.createDoc(contact.class.Organization, _space, object)
dispatch('close')
}
</script>
<Card label={'Create organization'}
okAction={createOrganization}
canSave={object.name.length > 0}
spaceClass={contact.class.Organizations}
spaceLabel={contact.string.OrganizationsFolder}
spacePlaceholder={contact.string.SelectFolder}
bind:space={_space}
on:close={() => { dispatch('close') }}>
<div class="flex-row-center">
<div class="mr-4 flex-center logo">
<Company size={'large'} />
</div>
<div class="flex-col">
<div class="fs-title"><EditBox placeholder="Apple" maxWidth="10rem" bind:value={object.name}/></div>
</div>
</div>
<div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
<span><Label label={contact.string.AddSocialLinks} /></span>
{:else}
<Channels value={object.channels} size={'small'} />
<div class="ml-1">
<CircleButton icon={IconEdit} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
</div>
{/if}
</div>
</Card>
<style lang="scss">
.logo {
width: 5rem;
height: 5rem;
color: var(--primary-button-color);
background-color: var(--primary-button-enabled);
border-radius: 50%;
}
.channels {
margin-top: 1.25rem;
span { margin-left: .5rem; }
}
</style>

View File

@ -0,0 +1,55 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { IconFolder, EditBox, ToggleWithLabel, Grid } from '@anticrm/ui'
import { getClient, SpaceCreateCard } from '@anticrm/presentation'
import contact from '../plugin'
import core, { getCurrentAccount } from '@anticrm/core'
const dispatch = createEventDispatcher()
let name: string = ''
let description: string = ''
export function canClose(): boolean {
return name === ''
}
const client = getClient()
function createChannel() {
client.createDoc(contact.class.Organizations, core.space.Model, {
name,
description,
private: false,
members: [getCurrentAccount()._id]
})
}
</script>
<SpaceCreateCard
label={contact.string.CreateOrganizations}
okAction={createChannel}
canSave={name ? true : false}
on:close={() => { dispatch('close') }}
>
<Grid column={1} rowGap={1.5}>
<EditBox label={contact.string.Name} icon={IconFolder} bind:value={name} placeholder='Organizations' focus/>
<ToggleWithLabel label={contact.string.MakePrivate} description={contact.string.MakePrivateDescription}/>
</Grid>
</SpaceCreateCard>

View File

@ -0,0 +1,96 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref, Space, Data } from '@anticrm/core'
import { getClient, Card, Channels, Avatar } from '@anticrm/presentation'
import { EditBox, showPopup, CircleButton, IconEdit, IconAdd, Label } from '@anticrm/ui'
import SocialEditor from './SocialEditor.svelte'
import { combineName, Person } from '@anticrm/contact'
import contact from '../plugin'
export let space: Ref<Space>
let _space = space
let firstName = ''
let lastName = ''
export function canClose(): boolean {
return firstName === '' && lastName === ''
}
const object: Person = {} as Person
const dispatch = createEventDispatcher()
const client = getClient()
async function createPerson() {
const person: Data<Person> = {
name: combineName(firstName, lastName),
city: object.city,
channels: object.channels
}
await client.createDoc(contact.class.Person, _space, person)
dispatch('close')
}
</script>
<Card label={contact.string.CreatePerson}
okAction={createPerson}
canSave={firstName.length > 0 && lastName.length > 0}
spaceClass={contact.class.Persons}
spaceLabel={contact.string.PersonsFolder}
spacePlaceholder={contact.string.SelectFolder}
bind:space={_space}
on:close={() => { dispatch('close') }}>
<div class="flex-row-center">
<div class="mr-4">
<Avatar avatar={object.avatar} size={'large'} />
</div>
<div class="flex-col">
<div class="fs-title"><EditBox placeholder="John" maxWidth="10rem" bind:value={firstName}/></div>
<div class="fs-title mb-1"><EditBox placeholder="Appleseed" maxWidth="10rem" bind:value={lastName}/></div>
<div class="small-text"><EditBox placeholder="Location" maxWidth="10rem" bind:value={object.city}/></div>
</div>
</div>
<div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
<span><Label label={contact.string.AddSocialLinks} /></span>
{:else}
<Channels value={object.channels} size={'small'} />
<div class="ml-1">
<CircleButton icon={IconEdit} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
</div>
{/if}
</div>
</Card>
<style lang="scss">
.channels {
margin-top: 1.25rem;
span { margin-left: .5rem; }
}
</style>

View File

@ -0,0 +1,55 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { IconFolder, EditBox, ToggleWithLabel, Grid } from '@anticrm/ui'
import { getClient, SpaceCreateCard } from '@anticrm/presentation'
import contact from '../plugin'
import core, { getCurrentAccount } from '@anticrm/core'
const dispatch = createEventDispatcher()
let name: string = ''
let description: string = ''
export function canClose(): boolean {
return name === ''
}
const client = getClient()
function createChannel() {
client.createDoc(contact.class.Persons, core.space.Model, {
name,
description,
private: false,
members: [getCurrentAccount()._id]
})
}
</script>
<SpaceCreateCard
label={contact.string.CreatePersons}
okAction={createChannel}
canSave={name ? true : false}
on:close={() => { dispatch('close') }}
>
<Grid column={1} rowGap={1.5}>
<EditBox label={contact.string.Name} icon={IconFolder} bind:value={name} placeholder='Folder' focus/>
<ToggleWithLabel label={contact.string.MakePrivate} description={contact.string.MakePrivateDescription}/>
</Grid>
</SpaceCreateCard>

View File

@ -0,0 +1,103 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref } from '@anticrm/core'
import { CircleButton, EditBox, showPopup, IconEdit, IconAdd, Label, AnyComponent, Component } from '@anticrm/ui'
import { getClient, createQuery, Channels } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel'
import contact from '../plugin'
import { Organization } from '@anticrm/contact'
import Company from './icons/Company.svelte'
import attachment from '@anticrm/attachment'
export let _id: Ref<Organization>
let object: Organization
let rightSection: AnyComponent | undefined
let fullSize: boolean = false
const client = getClient()
const query = createQuery()
$: query.query(contact.class.Organization, { _id }, result => { object = result[0] })
const dispatch = createEventDispatcher()
function saveChannels(result: any) {
if (result !== undefined) {
object.channels = result
client.updateDoc(object._class, object.space, object._id, { channels: result })
}
}
function nameChange() {
client.updateDoc(object._class, object.space, object._id, { name: object.name })
}
</script>
{#if object !== undefined}
<Panel icon={contact.icon.Company} title={object.name} {rightSection} {fullSize} {object} on:close={() => { dispatch('close') }}>
<div class="flex-row-center">
<div class="mr-8 flex-center logo">
<Company size={'large'} />
</div>
<div class="flex-col">
<div class="name"><EditBox placeholder="John" maxWidth="20rem" bind:value={object.name} on:change={ nameChange }/></div>
<div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
<span><Label label={contact.string.AddSocialLinks} /></span>
{:else}
<Channels value={object.channels} size={'small'} on:click={(ev) => {
if (ev.detail.presenter) {
fullSize = true
rightSection = ev.detail.presenter
}
}} />
<div class="ml-1">
<CircleButton icon={IconEdit} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
</div>
{/if}
</div>
</div>
</div>
<div class="mt-14">
<Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space }} />
</div>
</Panel>
{/if}
<style lang="scss">
.logo {
width: 5rem;
height: 5rem;
color: var(--primary-button-color);
background-color: var(--primary-button-enabled);
border-radius: 50%;
}
.name {
font-weight: 500;
font-size: 1.25rem;
color: var(--theme-caption-color);
}
.channels {
margin-top: .75rem;
span { margin-left: .5rem; }
}
</style>

View File

@ -0,0 +1,105 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref } from '@anticrm/core'
import { CircleButton, EditBox, showPopup, IconEdit, IconAdd, Label, AnyComponent, Component } from '@anticrm/ui'
import { AttributesBar, getClient, createQuery, Channels, Avatar } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel'
import contact from '../plugin'
import { combineName, formatName, getFirstName, getLastName, Person } from '@anticrm/contact'
import attachment from '@anticrm/attachment'
export let _id: Ref<Person>
let object: Person
let rightSection: AnyComponent | undefined
let fullSize: boolean = false
let firstName = ''
let lastName = ''
const client = getClient()
const query = createQuery()
$: query.query(contact.class.Person, { _id }, result => { object = result[0]; firstName = getFirstName(result[0].name); lastName = getLastName(result[0].name)})
const dispatch = createEventDispatcher()
function saveChannels(result: any) {
if (result !== undefined) {
object.channels = result
client.updateDoc(object._class, object.space, object._id, { channels: result })
}
}
function firstNameChange() {
client.updateDoc(object._class, object.space, object._id, { name: combineName(firstName, getLastName(object.name)) })
}
function lastNameChange() {
client.updateDoc(object._class, object.space, object._id, { name: combineName(getFirstName(object.name), lastName) })
}
</script>
{#if object !== undefined}
<Panel icon={contact.icon.Person} title={formatName(object.name)} {rightSection} {fullSize} {object} on:close={() => { dispatch('close') }}>
<AttributesBar {object} keys={['city']} slot="subtitle" />
<div class="flex-row-center">
<div class="mr-8">
<Avatar avatar={object.avatar} size={'x-large'} />
</div>
<div class="flex-col">
<div class="name"><EditBox placeholder="John" maxWidth="20rem" bind:value={firstName} on:change={ firstNameChange }/></div>
<div class="name"><EditBox placeholder="Appleseed" maxWidth="20rem" bind:value={lastName} on:change={ lastNameChange }/></div>
<div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
<span><Label label={contact.string.AddSocialLinks} /></span>
{:else}
<Channels value={object.channels} size={'small'} on:click={(ev) => {
if (ev.detail.presenter) {
fullSize = true
rightSection = ev.detail.presenter
}
}} />
<div class="ml-1">
<CircleButton icon={IconEdit} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
</div>
{/if}
</div>
</div>
</div>
<div class="mt-14">
<Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space }} />
</div>
</Panel>
{/if}
<style lang="scss">
.name {
font-weight: 500;
font-size: 1.25rem;
color: var(--theme-caption-color);
}
.channels {
margin-top: .75rem;
span { margin-left: .5rem; }
}
</style>

View File

@ -0,0 +1,62 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { getResource } from '@anticrm/platform'
import { formatName, Person } from '@anticrm/contact'
import { Avatar, getClient } from '@anticrm/presentation'
import { showPopup } from '@anticrm/ui'
import view from '@anticrm/view'
import Company from './icons/Company.svelte';
export let value: Person
async function onClick() {
const client = getClient()
const hierarchy = client.getHierarchy()
const clazz = hierarchy.getClass(value._class)
const editorMixin = hierarchy.as(clazz, view.mixin.ObjectEditor)
const editor = await getResource(editorMixin.editor)
showPopup(editor, { _id: value._id }, 'full')
}
</script>
<div class="flex-row-center user-container" on:click={onClick}>
<div class="icon"><Company size={'medium'} /></div>
<div class="overflow-label user">{value.name}</div>
</div>
<style lang="scss">
.user-container {
cursor: pointer;
.icon {
width: 1.5rem;
height: 1.5rem;
}
.user {
margin-left: .5rem;
font-weight: 500;
text-align: left;
color: var(--theme-content-accent-color);
}
&:hover .user {
text-decoration: underline;
color: var(--theme-caption-color);
}
}
</style>

View File

@ -20,7 +20,8 @@
import { EditBox, Button, ScrollBox } from '@anticrm/ui' import { EditBox, Button, ScrollBox } from '@anticrm/ui'
import { getClient } from '@anticrm/presentation' import { getClient } from '@anticrm/presentation'
import contact, { ChannelProvider, Channel } from '@anticrm/contact' import { ChannelProvider, Channel } from '@anticrm/contact'
import contact from '../plugin'
export let values: Channel[] export let values: Channel[]
let newValues: Channel[] = [] let newValues: Channel[] = []
@ -63,14 +64,9 @@
<EditBox label={provider.label} placeholder={provider.placeholder} bind:value={newValues[i].value} maxWidth={'14.5rem'}/> <EditBox label={provider.label} placeholder={provider.placeholder} bind:value={newValues[i].value} maxWidth={'14.5rem'}/>
{/each} {/each}
</div> </div>
<!-- <div class="popup-block">
<span>SOCIAL LINKS</span>
<EditBox label={'Twitter'} placeholder={'@rosychen'} maxWidth={'12.5rem'} />
<EditBox label={'Facebook'} placeholder={'facebook/rosamundch'} maxWidth={'12.5rem'} />
</div> -->
</ScrollBox> </ScrollBox>
<div class="buttons"> <div class="buttons">
<div class="btn"><Button label="Apply" width={'100%'} on:click={() => { dispatch('close', filterUndefined(newValues)) }}/></div> <div class="btn"><Button label={contact.string.Apply} width={'100%'} on:click={() => { dispatch('close', filterUndefined(newValues)) }}/></div>
</div> </div>
</div> </div>
@ -106,6 +102,5 @@
align-items: center; align-items: center;
margin-top: 1rem; margin-top: 1rem;
.btn { flex-grow: 1; } .btn { flex-grow: 1; }
// .btn + .btn { margin-left: .75rem; }
} }
</style> </style>

View File

@ -16,9 +16,9 @@
<script lang="ts"> <script lang="ts">
export let size: 'small' | 'medium' | 'large' export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)' const fill: string = 'currentColor'
</script> </script>
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M5,14.8c-1.8,0-3.6-0.6-5-1.5c1.2,0.1,3.4-0.1,4.8-1.4c-2-0.1-3-1.7-3.1-2.4c0.2,0.1,1,0.2,1.5,0C0.8,8.8,0.5,6.7,0.5,6 C1,6.3,1.7,6.4,2,6.4c-2.2-1.6-1.4-4-1-4.5c1.6,2.2,3.9,3.5,6.8,3.6C7.7,5.2,7.7,4.9,7.7,4.7c0-1.9,1.5-3.4,3.3-3.4 c1,0,1.8,0.4,2.4,1.1c0.6-0.2,1.6-0.5,2.1-0.8c-0.2,0.9-1,1.6-1.4,1.9c0,0,0,0,0,0c0.4-0.1,1.5-0.3,1.9-0.6c-0.2,0.5-1,1.3-1.6,1.8 C14.5,10,10.4,14.8,5,14.8z"/> <path d="M15.3,14.7h-0.7V4c0-0.3-0.2-0.6-0.5-0.6l-7.3-2c-0.2-0.1-0.4,0-0.6,0.1C6.1,1.6,6,1.8,6,2v3.3H2 C1.6,5.3,1.3,5.6,1.3,6v8.7H0.7C0.3,14.7,0,15,0,15.3C0,15.7,0.3,16,0.7,16h14.7c0.4,0,0.7-0.3,0.7-0.7C16,15,15.7,14.7,15.3,14.7z M2.7,14.7v-8h6v8H2.7z M9.3,5.3h-2V2.9l6,1.6v10.2H10V6C10,5.6,9.7,5.3,9.3,5.3z"/>
</svg> </svg>

View File

@ -15,11 +15,27 @@
// //
import PersonPresenter from './components/PersonPresenter.svelte' import PersonPresenter from './components/PersonPresenter.svelte'
import OrganizationPresenter from './components/OrganizationPresenter.svelte'
import ChannelsPresenter from './components/ChannelsPresenter.svelte' import ChannelsPresenter from './components/ChannelsPresenter.svelte'
import CreatePerson from './components/CreatePerson.svelte'
import CreateOrganization from './components/CreateOrganization.svelte'
import EditPerson from './components/EditPerson.svelte'
import EditOrganization from './components/EditOrganization.svelte'
import CreatePersons from './components/CreatePersons.svelte'
import CreateOrganizations from './components/CreateOrganizations.svelte'
import SocialEditor from './components/SocialEditor.svelte'
export default async () => ({ export default async () => ({
component: { component: {
PersonPresenter, PersonPresenter,
ChannelsPresenter OrganizationPresenter,
ChannelsPresenter,
CreatePerson,
CreateOrganization,
EditPerson,
EditOrganization,
CreatePersons,
CreateOrganizations,
SocialEditor
}, },
}) })

View File

@ -13,9 +13,24 @@
// limitations under the License. // limitations under the License.
// //
import { mergeIds } from '@anticrm/platform' import { IntlString, mergeIds } from '@anticrm/platform'
import contact, { contactId } from '@anticrm/contact' import contact, { contactId } from '@anticrm/contact'
export default mergeIds(contactId, contact, { export default mergeIds(contactId, contact, {
string: {
Apply: '' as IntlString,
Contacts: '' as IntlString,
CreatePerson: '' as IntlString,
CreatePersons: '' as IntlString,
CreateOrganizations: '' as IntlString,
Organizations: '' as IntlString,
SelectFolder: '' as IntlString,
OrganizationsFolder: '' as IntlString,
PersonsFolder: '' as IntlString,
AddSocialLinks: '' as IntlString,
Name: '' as IntlString,
MakePrivate: '' as IntlString,
MakePrivateDescription: '' as IntlString
}
}) })

View File

@ -18,6 +18,16 @@ import type { Plugin, Asset } from '@anticrm/platform'
import type { Doc, Ref, Class, UXObject, Space, Account } from '@anticrm/core' import type { Doc, Ref, Class, UXObject, Space, Account } from '@anticrm/core'
import type { AnyComponent } from '@anticrm/ui' import type { AnyComponent } from '@anticrm/ui'
/**
* @public
*/
export interface Organizations extends Space {}
/**
* @public
*/
export interface Persons extends Space {}
/** /**
* @public * @public
*/ */
@ -40,6 +50,8 @@ export interface Channel {
export interface Contact extends Doc { export interface Contact extends Doc {
name: string name: string
avatar?: string avatar?: string
attachments?: number
comments?: number
channels: Channel[] channels: Channel[]
} }
@ -47,8 +59,6 @@ export interface Contact extends Doc {
* @public * @public
*/ */
export interface Person extends Contact { export interface Person extends Contact {
// email: string
// phone: string
city: string city: string
} }
@ -112,10 +122,15 @@ export default plugin(contactId, {
ChannelProvider: '' as Ref<Class<ChannelProvider>>, ChannelProvider: '' as Ref<Class<ChannelProvider>>,
Contact: '' as Ref<Class<Contact>>, Contact: '' as Ref<Class<Contact>>,
Person: '' as Ref<Class<Person>>, Person: '' as Ref<Class<Person>>,
Persons: '' as Ref<Class<Persons>>,
Organization: '' as Ref<Class<Organization>>, Organization: '' as Ref<Class<Organization>>,
Organizations: '' as Ref<Class<Organizations>>,
Employee: '' as Ref<Class<Employee>>, Employee: '' as Ref<Class<Employee>>,
EmployeeAccount: '' as Ref<Class<EmployeeAccount>> EmployeeAccount: '' as Ref<Class<EmployeeAccount>>
}, },
component: {
SocialEditor: '' as AnyComponent
},
channelProvider: { channelProvider: {
Email: '' as Ref<ChannelProvider>, Email: '' as Ref<ChannelProvider>,
Phone: '' as Ref<ChannelProvider>, Phone: '' as Ref<ChannelProvider>,
@ -136,7 +151,9 @@ export default plugin(contactId, {
VK: '' as Asset, VK: '' as Asset,
WhatsApp: '' as Asset, WhatsApp: '' as Asset,
Youtube: '' as Asset, Youtube: '' as Asset,
GitHub: '' as Asset GitHub: '' as Asset,
Person: '' as Asset,
Company: '' as Asset
}, },
space: { space: {
Employee: '' as Ref<Space> Employee: '' as Ref<Space>

View File

@ -3,12 +3,6 @@
<path d="M25.9,14.6C25.7,9.8,21.9,6,17,5.7h-0.5c0,0,0,0,0,0c-1.4,0-2.9,0.3-4.2,1c-3.2,1.6-5.2,4.8-5.2,8.4c0,1.4,0.3,2.7,0.9,4 l-1.9,5.7c-0.1,0.2,0,0.5,0.1,0.6c0.1,0.1,0.3,0.2,0.4,0.2c0.1,0,0.1,0,0.2,0l5.7-1.9c1.2,0.6,2.6,0.9,4,0.9c0,0,0,0,0,0 c3.6,0,6.8-2,8.4-5.2c0.7-1.3,1-2.8,1-4.2L25.9,14.6z M24.7,15.1C24.7,15.1,24.7,15.1,24.7,15.1c0,1.3-0.3,2.5-0.9,3.7 c-1.4,2.8-4.2,4.5-7.3,4.5c0,0,0,0,0,0c-1.3,0-2.5-0.3-3.6-0.9c-0.1-0.1-0.3-0.1-0.5,0l-4.8,1.6l1.6-4.8c0.1-0.2,0-0.3,0-0.5 c-0.6-1.1-0.9-2.4-0.9-3.7c0-3.1,1.7-5.9,4.5-7.3c1.1-0.6,2.4-0.9,3.6-0.9c0,0,0,0,0,0l0.5,0c4.2,0.2,7.5,3.6,7.7,7.7V15.1z"/> <path d="M25.9,14.6C25.7,9.8,21.9,6,17,5.7h-0.5c0,0,0,0,0,0c-1.4,0-2.9,0.3-4.2,1c-3.2,1.6-5.2,4.8-5.2,8.4c0,1.4,0.3,2.7,0.9,4 l-1.9,5.7c-0.1,0.2,0,0.5,0.1,0.6c0.1,0.1,0.3,0.2,0.4,0.2c0.1,0,0.1,0,0.2,0l5.7-1.9c1.2,0.6,2.6,0.9,4,0.9c0,0,0,0,0,0 c3.6,0,6.8-2,8.4-5.2c0.7-1.3,1-2.8,1-4.2L25.9,14.6z M24.7,15.1C24.7,15.1,24.7,15.1,24.7,15.1c0,1.3-0.3,2.5-0.9,3.7 c-1.4,2.8-4.2,4.5-7.3,4.5c0,0,0,0,0,0c-1.3,0-2.5-0.3-3.6-0.9c-0.1-0.1-0.3-0.1-0.5,0l-4.8,1.6l1.6-4.8c0.1-0.2,0-0.3,0-0.5 c-0.6-1.1-0.9-2.4-0.9-3.7c0-3.1,1.7-5.9,4.5-7.3c1.1-0.6,2.4-0.9,3.6-0.9c0,0,0,0,0,0l0.5,0c4.2,0.2,7.5,3.6,7.7,7.7V15.1z"/>
</symbol> </symbol>
<symbol id="hashtag" viewBox="0 0 16 16">
<path d="M14,9.6h-3.2l0.4-3.2H14c0.3,0,0.6-0.3,0.6-0.6S14.3,5.2,14,5.2h-2.7l0.4-3.7c0-0.3-0.2-0.6-0.5-0.7 c-0.3,0-0.6,0.2-0.7,0.5l-0.4,3.8H6.9l0.4-3.7c0-0.3-0.2-0.6-0.5-0.7c-0.3,0-0.6,0.2-0.7,0.5L5.7,5.2H2.3C2,5.2,1.7,5.5,1.7,5.8 S2,6.4,2.3,6.4h3.2L5.2,9.6H2.3c-0.3,0-0.6,0.3-0.6,0.6s0.3,0.6,0.6,0.6h2.7l-0.4,3.7c0,0.3,0.2,0.6,0.5,0.7c0,0,0,0,0.1,0 c0.3,0,0.6-0.2,0.6-0.5l0.4-3.8h3.2L9,14.5c0,0.3,0.2,0.6,0.5,0.7c0,0,0,0,0.1,0c0.3,0,0.6-0.2,0.6-0.5l0.4-3.8H14 c0.3,0,0.6-0.3,0.6-0.6S14.3,9.6,14,9.6z M6.4,9.6l0.4-3.2h3.2L9.6,9.6H6.4z"/>
</symbol>
<symbol id="lock" viewBox="0 0 16 16">
<path d="M13,6.9h-1.1V4.8c0-2.2-1.8-3.9-3.9-3.9c-2.2,0-3.9,1.8-3.9,3.9v2.1H3c-0.9,0-1.6,0.7-1.6,1.6v5.3 c0,0.9,0.7,1.6,1.6,1.6h10c0.9,0,1.6-0.7,1.6-1.6V8.5C14.6,7.6,13.9,6.9,13,6.9z M5.3,4.8c0-1.5,1.2-2.7,2.7-2.7s2.7,1.2,2.7,2.7 v2.1H5.3V4.8z M13.4,13.8c0,0.2-0.2,0.4-0.4,0.4H3c-0.2,0-0.4-0.2-0.4-0.4V8.5c0-0.2,0.2-0.4,0.4-0.4h10c0.2,0,0.4,0.2,0.4,0.4V13.8 z"/>
</symbol>
<symbol id="recruitment" viewBox="0 0 24 24"> <symbol id="recruitment" viewBox="0 0 24 24">
<g> <g>
<path d="M9.6,14.4c-1.8,0-7.4,0-7.4,3.4c0,3,4.2,3.4,7.4,3.4c1.8,0,7.4,0,7.4-3.4C17.1,14.7,12.8,14.4,9.6,14.4z M9.6,20c-4.1,0-6.2-0.7-6.2-2.2c0-1.5,2.1-2.2,6.2-2.2s6.2,0.7,6.2,2.2C15.9,19.2,13.8,20,9.6,20z"/> <path d="M9.6,14.4c-1.8,0-7.4,0-7.4,3.4c0,3,4.2,3.4,7.4,3.4c1.8,0,7.4,0,7.4-3.4C17.1,14.7,12.8,14.4,9.6,14.4z M9.6,20c-4.1,0-6.2-0.7-6.2-2.2c0-1.5,2.1-2.2,6.2-2.2s6.2,0.7,6.2,2.2C15.9,19.2,13.8,20,9.6,20z"/>
@ -33,9 +27,6 @@
/> />
</g> </g>
</symbol> </symbol>
<symbol id="company" viewBox="0 0 16 16">
<path d="M15.3,14.7h-0.7V4c0-0.3-0.2-0.6-0.5-0.6l-7.3-2c-0.2-0.1-0.4,0-0.6,0.1C6.1,1.6,6,1.8,6,2v3.3H2 C1.6,5.3,1.3,5.6,1.3,6v8.7H0.7C0.3,14.7,0,15,0,15.3C0,15.7,0.3,16,0.7,16h14.7c0.4,0,0.7-0.3,0.7-0.7C16,15,15.7,14.7,15.3,14.7z M2.7,14.7v-8h6v8H2.7z M9.3,5.3h-2V2.9l6,1.6v10.2H10V6C10,5.6,9.7,5.3,9.3,5.3z"/>
</symbol>
<symbol id="calendar" viewBox="0 0 24 24"> <symbol id="calendar" viewBox="0 0 24 24">
<path d="M19.5,5h-2.1V4.5c0-0.3-0.2-0.5-0.5-0.5s-0.5,0.2-0.5,0.5V5H8.1V4.5C8.1,4.2,7.9,4,7.6,4S7.1,4.2,7.1,4.5V5H5 C4.2,5,3.5,5.7,3.5,6.5V19c0,0.8,0.7,1.5,1.5,1.5h14.5c0.8,0,1.5-0.7,1.5-1.5V6.5C21,5.7,20.3,5,19.5,5z M5,6h2.1v0.5 c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h8.3v0.5c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h2.1C19.7,6,20,6.3,20,6.5v3.1H4.5V6.5 C4.5,6.3,4.7,6,5,6z M19.5,19.5H5c-0.3,0-0.5-0.2-0.5-0.5v-8.3H20V19C20,19.2,19.7,19.5,19.5,19.5z" /> <path d="M19.5,5h-2.1V4.5c0-0.3-0.2-0.5-0.5-0.5s-0.5,0.2-0.5,0.5V5H8.1V4.5C8.1,4.2,7.9,4,7.6,4S7.1,4.2,7.1,4.5V5H5 C4.2,5,3.5,5.7,3.5,6.5V19c0,0.8,0.7,1.5,1.5,1.5h14.5c0.8,0,1.5-0.7,1.5-1.5V6.5C21,5.7,20.3,5,19.5,5z M5,6h2.1v0.5 c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h8.3v0.5c0,0.3,0.2,0.5,0.5,0.5s0.5-0.2,0.5-0.5V6h2.1C19.7,6,20,6.3,20,6.5v3.1H4.5V6.5 C4.5,6.3,4.7,6,5,6z M19.5,19.5H5c-0.3,0-0.5-0.2-0.5-0.5v-8.3H20V19C20,19.2,19.7,19.5,19.5,19.5z" />
</symbol> </symbol>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -14,7 +14,6 @@
"MakePrivateDescription": "Only members can see it", "MakePrivateDescription": "Only members can see it",
"CreateAnApplication": "Create an application", "CreateAnApplication": "Create an application",
"NoApplicationsForCandidate": "There are no applications for this candidate.", "NoApplicationsForCandidate": "There are no applications for this candidate.",
"UploadDropFilesHere": "Upload or drop files here",
"NoAttachmentsForCandidate": "There are no attachments for this candidate." "NoAttachmentsForCandidate": "There are no attachments for this candidate."
}, },
"status": { "status": {

View File

@ -21,7 +21,6 @@ loadMetadata(recruit.icon, {
RecruitApplication: `${icons}#recruitment`, RecruitApplication: `${icons}#recruitment`,
Vacancy: `${icons}#vacancy`, Vacancy: `${icons}#vacancy`,
Location: `${icons}#location`, Location: `${icons}#location`,
Company: `${icons}#company`,
Calendar: `${icons}#calendar`, Calendar: `${icons}#calendar`,
Create: `${icons}#create` Create: `${icons}#create`
}) })

View File

@ -43,7 +43,8 @@
"@anticrm/login": "~0.6.0", "@anticrm/login": "~0.6.0",
"deep-equal": "^2.0.5", "deep-equal": "^2.0.5",
"@anticrm/panel": "~0.6.0", "@anticrm/panel": "~0.6.0",
"@anticrm/activity": "~0.6.0", "@anticrm/activity":"~0.6.0",
"@anticrm/attachment": "~0.6.0",
"@anticrm/chunter-resources": "~0.6.0", "@anticrm/chunter-resources": "~0.6.0",
"@anticrm/view": "~0.6.0", "@anticrm/view": "~0.6.0",
"@anticrm/view-resources": "~0.6.0" "@anticrm/view-resources": "~0.6.0"

View File

@ -1,142 +0,0 @@
<!--
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { CircleButton, IconAdd, showPopup, Spinner, Label } from '@anticrm/ui'
import type { Doc, Ref, Space, Class, Bag } from '@anticrm/core'
import { setPlatformStatus, unknownError } from '@anticrm/platform'
import { generateId } from '@anticrm/core'
import { createQuery, getClient, PDFViewer } from '@anticrm/presentation'
import type { Attachment } from '@anticrm/chunter'
import { Table } from '@anticrm/view-resources'
import { uploadFile } from '../utils'
import UploadDuo from './icons/UploadDuo.svelte'
import chunter from '@anticrm/chunter'
import recruit from '../plugin'
export let objectId: Ref<Doc>
export let space: Ref<Space>
export let _class: Ref<Class<Doc>>
let attachments: Attachment[] = []
const query = createQuery()
$: query.query(chunter.class.Attachment, { attachedTo: objectId }, result => { attachments = result })
let inputFile: HTMLInputElement
let loading = 0
const client = getClient()
async function createAttachment(file: File) {
loading++
try {
const uuid = await uploadFile(space, file, objectId)
console.log('uploaded file uuid', uuid)
client.addCollection(chunter.class.Attachment, space, objectId, _class, 'attachments', {
name: file.name,
file: uuid,
type: file.type,
size: file.size,
lastModified: file.lastModified
})
} catch (err: any) {
setPlatformStatus(unknownError(err))
} finally {
loading--
}
}
function fileSelected () {
console.log(inputFile.files)
const list = inputFile.files
if (list === null || list.length === 0) return
for (let index = 0; index < list.length; index++) {
const file = list.item(index)
if (file !== null) createAttachment(file)
}
}
function fileDrop (e: DragEvent) {
const list = e.dataTransfer?.files
if (list === undefined || list.length === 0) return
for (let index = 0; index < list.length; index++) {
const file = list.item(index)
if (file !== null) createAttachment(file)
}
}
let dragover = false
</script>
<div class="attachments-container">
<div class="flex-row-center">
<span class="title">Attachments</span>
{#if loading}
<Spinner/>
{:else}
<CircleButton icon={IconAdd} size={'small'} on:click={ () => { inputFile.click() } } />
{/if}
<input bind:this={inputFile} multiple type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
</div>
{#if attachments.length === 0 && !loading}
<div class="flex-col-center mt-5 zone-container" class:solid={dragover}
on:dragover|preventDefault={ () => { dragover = true } }
on:dragleave={ () => { dragover = false } }
on:drop|preventDefault|stopPropagation={fileDrop}
>
<UploadDuo size={'large'} />
<div class="small-text content-dark-color mt-2">
<Label label={recruit.string.NoAttachmentsForCandidate} />
</div>
<div class="small-text">
<a href={'#'} on:click={() => inputFile.click()}><Label label={recruit.string.UploadDropFilesHere} /></a>
</div>
</div>
{:else}
<Table
_class={chunter.class.Attachment}
config={['', 'lastModified']}
options={ {} }
query={ { attachedTo: objectId } }
/>
{/if}
</div>
<style lang="scss">
.attachments-container {
display: flex;
flex-direction: column;
.title {
margin-right: .75rem;
font-weight: 500;
font-size: 1.25rem;
color: var(--theme-caption-color);
}
}
.zone-container {
padding: 1rem;
color: var(--theme-caption-color);
background: rgba(255, 255, 255, .03);
border: 1px dashed rgba(255, 255, 255, .16);
border-radius: .75rem;
}
</style>

View File

@ -26,15 +26,15 @@
import recruit from '../plugin' import recruit from '../plugin'
import chunter from '@anticrm/chunter' import chunter from '@anticrm/chunter'
import type { Candidate } from '@anticrm/recruit' import type { Candidate } from '@anticrm/recruit'
import type { Attachment } from '@anticrm/chunter' import attachment from '@anticrm/attachment'
import type { Attachment } from '@anticrm/attachment'
import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon, IconAdd, Spinner, Label, Status as StatusComponent } from '@anticrm/ui' import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon, IconAdd, Spinner, Label, Status as StatusComponent } from '@anticrm/ui'
import FileUpload from './icons/FileUpload.svelte' import FileUpload from './icons/FileUpload.svelte'
import Edit from './icons/Edit.svelte' import Edit from './icons/Edit.svelte'
import SocialEditor from './SocialEditor.svelte'
import YesNo from './YesNo.svelte' import YesNo from './YesNo.svelte'
import { combineName } from '@anticrm/contact'; import contact, { combineName } from '@anticrm/contact'
export let space: Ref<Space> export let space: Ref<Space>
@ -75,7 +75,7 @@
console.log('resume name', resume.name) console.log('resume name', resume.name)
if (resume.uuid !== undefined) { if (resume.uuid !== undefined) {
client.addCollection(chunter.class.Attachment, space, id, recruit.class.Candidate, 'attachments', { client.addCollection(attachment.class.Attachment, space, id, recruit.class.Candidate, 'attachments', {
name: resume.name, name: resume.name,
file: resume.uuid, file: resume.uuid,
size: resume.size, size: resume.size,
@ -147,12 +147,12 @@
<div class="flex-row-center channels"> <div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0} {#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} /> <CircleButton icon={IconAdd} size={'small'} transparent on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
<span><Label label={'Add social links'} /></span> <span><Label label={'Add social links'} /></span>
{:else} {:else}
<Channels value={object.channels} size={'small'} /> <Channels value={object.channels} size={'small'} />
<div class="ml-1"> <div class="ml-1">
<CircleButton icon={Edit} size={'small'} transparent on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} /> <CircleButton icon={Edit} size={'small'} transparent on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
</div> </div>
{/if} {/if}
</div> </div>
@ -179,10 +179,6 @@
<div class="row"><Label label={'Onsite'} /><YesNo bind:value={object.onsite} /></div> <div class="row"><Label label={'Onsite'} /><YesNo bind:value={object.onsite} /></div>
<div class="row"><Label label={'Remote'} /><YesNo bind:value={object.remote} /></div> <div class="row"><Label label={'Remote'} /><YesNo bind:value={object.remote} /></div>
</div> </div>
<!-- <svelte:fragment slot="contacts">
<Channels value={object.channels} />
<CircleButton icon={Edit} label={'Edit'} on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { object.channels = result })} />
</svelte:fragment> -->
</Card> </Card>
<style lang="scss"> <style lang="scss">

View File

@ -19,14 +19,15 @@
import { createQuery } from '@anticrm/presentation' import { createQuery } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel' import { Panel } from '@anticrm/panel'
import type { Candidate, Applicant, Vacancy } from '@anticrm/recruit' import type { Candidate, Applicant, Vacancy } from '@anticrm/recruit'
import attachment from '@anticrm/attachment'
import Contact from './icons/Contact.svelte' import Contact from './icons/Contact.svelte'
import Attachments from './Attachments.svelte'
import CandidateCard from './CandidateCard.svelte' import CandidateCard from './CandidateCard.svelte'
import VacancyCard from './VacancyCard.svelte' import VacancyCard from './VacancyCard.svelte'
import recruit from '../plugin' import recruit from '../plugin'
import { formatName } from '@anticrm/contact' import { formatName } from '@anticrm/contact'
import ApplicantHeader from './ApplicantHeader.svelte' import ApplicantHeader from './ApplicantHeader.svelte'
import { Component } from '@anticrm/ui'
export let _id: Ref<Applicant> export let _id: Ref<Applicant>
let object: Applicant let object: Applicant
@ -55,7 +56,7 @@
</div> </div>
<div class="attachments"> <div class="attachments">
<Attachments objectId={object._id} _class={object._class} space={object.space} {object}/> <Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space, object: object }} />
</div> </div>
</Panel> </Panel>

View File

@ -15,24 +15,18 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import type { Ref, Space, Doc, Class } from '@anticrm/core' import type { Ref } from '@anticrm/core'
import { CircleButton, EditBox, Link, showPopup, IconFile as FileIcon, IconAdd, Label, AnyComponent } from '@anticrm/ui' import { CircleButton, EditBox, showPopup, IconAdd, Label, AnyComponent, Component } from '@anticrm/ui'
import type { Attachment } from '@anticrm/chunter' import { getClient, createQuery, Channels, AttributeEditor, AttributesBar, Avatar } from '@anticrm/presentation'
import FileUpload from './icons/FileUpload.svelte'
import { getClient, createQuery, Channels, AttributeEditor, PDFViewer, Avatar } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel' import { Panel } from '@anticrm/panel'
import type { Candidate } from '@anticrm/recruit' import type { Candidate } from '@anticrm/recruit'
import Contact from './icons/Contact.svelte' import Contact from './icons/Contact.svelte'
import Attachments from './Attachments.svelte'
import Edit from './icons/Edit.svelte' import Edit from './icons/Edit.svelte'
import SocialEditor from './SocialEditor.svelte'
import AttributesBar from './AttributesBar.svelte'
import Applications from './Applications.svelte' import Applications from './Applications.svelte'
import attachment from '@anticrm/attachment'
import core from '@anticrm/core'
import recruit from '../plugin' import recruit from '../plugin'
import { combineName, formatName, getFirstName, getLastName } from '@anticrm/contact' import contact, { combineName, formatName, getFirstName, getLastName } from '@anticrm/contact'
export let _id: Ref<Candidate> export let _id: Ref<Candidate>
let object: Candidate let object: Candidate
@ -80,7 +74,7 @@
<!-- <div class="city"><AttributeEditor maxWidth="20rem" _class={recruit.class.Candidate} {object} key="city"/></div> --> <!-- <div class="city"><AttributeEditor maxWidth="20rem" _class={recruit.class.Candidate} {object} key="city"/></div> -->
<div class="flex-row-center channels"> <div class="flex-row-center channels">
{#if !object.channels || object.channels.length === 0} {#if !object.channels || object.channels.length === 0}
<CircleButton icon={IconAdd} size={'small'} selected on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} /> <CircleButton icon={IconAdd} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
<span><Label label={'Add social links'} /></span> <span><Label label={'Add social links'} /></span>
{:else} {:else}
<Channels value={object.channels} size={'small'} on:click={(ev) => { <Channels value={object.channels} size={'small'} on:click={(ev) => {
@ -90,7 +84,7 @@
} }
}} /> }} />
<div class="ml-1"> <div class="ml-1">
<CircleButton icon={Edit} size={'small'} selected on:click={(ev) => showPopup(SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} /> <CircleButton icon={Edit} size={'small'} selected on:click={(ev) => showPopup(contact.component.SocialEditor, { values: object.channels ?? [] }, ev.target, (result) => { saveChannels(result) })} />
</div> </div>
{/if} {/if}
</div> </div>
@ -102,7 +96,7 @@
</div> </div>
<div class="mt-14"> <div class="mt-14">
<Attachments objectId={object._id} _class={object._class} space={object.space} /> <Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space, noLabel: recruit.string.NoAttachmentsForCandidate }} />
</div> </div>
</Panel> </Panel>

View File

@ -19,13 +19,12 @@
import type { Ref } from '@anticrm/core' import type { Ref } from '@anticrm/core'
import { IconClose, Label, EditBox, ToggleWithLabel, Grid, Icon, Component } from '@anticrm/ui' import { IconClose, Label, EditBox, ToggleWithLabel, Grid, Icon, Component } from '@anticrm/ui'
import { TextEditor } from '@anticrm/text-editor' import { TextEditor } from '@anticrm/text-editor'
import { getClient, createQuery } from '@anticrm/presentation' import { AttributesBar, getClient, createQuery } from '@anticrm/presentation'
import { Vacancy } from '@anticrm/recruit' import { Vacancy } from '@anticrm/recruit'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import AttributesBar from './AttributesBar.svelte'
import activity from '@anticrm/activity' import activity from '@anticrm/activity'
import attachment from '@anticrm/attachment'
import recruit from '../plugin' import recruit from '../plugin'
import Attachments from './Attachments.svelte'
export let _id: Ref<Vacancy> export let _id: Ref<Vacancy>
@ -90,7 +89,7 @@
</div> </div>
</div> </div>
<div class="mt-14"> <div class="mt-14">
<Attachments objectId={object._id} _class={object._class} space={object.space} /> <Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space }} />
</div> </div>
{:else if selected === 1} {:else if selected === 1}
<ToggleWithLabel label={'This vacancy is private'} description={recruit.string.MakePrivateDescription}/> <ToggleWithLabel label={'This vacancy is private'} description={recruit.string.MakePrivateDescription}/>

View File

@ -1,28 +0,0 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="var(--duotone-color)" d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0-0.1-0.1 c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1 C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h6h6 c2,0,3.6-1.6,3.6-3.6S20,6.4,18,6.4z"/>
<g {fill}>
<path d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0 c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1-0.1c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3 C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1c0,0,0,0,0,0C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0 c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h0.6l1.2-1.2H6c-1.3,0-2.4-1.1-2.4-2.4c0-1.3,1.1-2.4,2.4-2.4h0.1 c0.2,0,0.4,0,0.6,0c0.2,0,0.4-0.1,0.6-0.2c0.2-0.1,0.3-0.3,0.4-0.4c0.1-0.1,0.1-0.2,0.2-0.3C7.8,6.5,7.9,6.4,8,6.2l0,0 c0.7-1.5,2.2-2.6,4-2.6s3.3,1.1,4,2.6l0,0c0.1,0.2,0.1,0.3,0.2,0.4c0,0.1,0.1,0.2,0.2,0.3c0.1,0.2,0.2,0.3,0.4,0.4 c0.2,0.1,0.4,0.2,0.6,0.2c0.2,0,0.4,0,0.6,0H18c1.3,0,2.4,1.1,2.4,2.4c0,1.3-1.1,2.4-2.4,2.4h-1.8l1.2,1.2H18c2,0,3.6-1.6,3.6-3.6 S20,6.4,18,6.4z"/>
<path d="M12,11.2l-4.4,4.4l0.8,0.8l3-3V21c0,0.3,0.3,0.6,0.6,0.6s0.6-0.3,0.6-0.6v-7.6l3,3l0.8-0.8L12,11.2z"/>
</g>
</svg>

View File

@ -20,7 +20,6 @@ import CreateCandidates from './components/CreateCandidates.svelte'
import CreateCandidate from './components/CreateCandidate.svelte' import CreateCandidate from './components/CreateCandidate.svelte'
import CreateApplication from './components/CreateApplication.svelte' import CreateApplication from './components/CreateApplication.svelte'
import EditCandidate from './components/EditCandidate.svelte' import EditCandidate from './components/EditCandidate.svelte'
import Attachments from './components/Attachments.svelte'
import KanbanCard from './components/KanbanCard.svelte' import KanbanCard from './components/KanbanCard.svelte'
import EditVacancy from './components/EditVacancy.svelte' import EditVacancy from './components/EditVacancy.svelte'
import ApplicationPresenter from './components/ApplicationPresenter.svelte' import ApplicationPresenter from './components/ApplicationPresenter.svelte'
@ -43,7 +42,6 @@ export default async (): Promise<Resources> => ({
CreateCandidate, CreateCandidate,
CreateApplication, CreateApplication,
EditCandidate, EditCandidate,
Attachments,
KanbanCard, KanbanCard,
ApplicationPresenter, ApplicationPresenter,
ApplicationsPresenter, ApplicationsPresenter,

View File

@ -38,7 +38,6 @@ export default mergeIds(recruitId, recruit, {
CreateCandidate: '' as IntlString, CreateCandidate: '' as IntlString,
CreateAnApplication: '' as IntlString, CreateAnApplication: '' as IntlString,
NoApplicationsForCandidate: '' as IntlString, NoApplicationsForCandidate: '' as IntlString,
UploadDropFilesHere: '' as IntlString,
NoAttachmentsForCandidate: '' as IntlString, NoAttachmentsForCandidate: '' as IntlString,
FirstName: '' as IntlString, FirstName: '' as IntlString,

View File

@ -39,8 +39,6 @@ export interface Candidates extends Space {}
*/ */
export interface Candidate extends Person { export interface Candidate extends Person {
title?: string title?: string
attachments?: number
comments?: number
applications?: number applications?: number
onsite?: boolean onsite?: boolean
remote?: boolean remote?: boolean
@ -71,7 +69,6 @@ export default plugin(recruitId, {
icon: { icon: {
RecruitApplication: '' as Asset, RecruitApplication: '' as Asset,
Vacancy: '' as Asset, Vacancy: '' as Asset,
Company: '' as Asset,
Location: '' as Asset, Location: '' as Asset,
Calendar: '' as Asset, Calendar: '' as Asset,
Create: '' as Asset Create: '' as Asset

View File

@ -13,7 +13,6 @@
"TaskName": "Task name *", "TaskName": "Task name *",
"TaskAssignee": "Assignee", "TaskAssignee": "Assignee",
"TaskDescription": "Description", "TaskDescription": "Description",
"UploadDropFilesHere": "Upload or drop files here",
"NoAttachmentsForTask": "There are no attachments for this task.", "NoAttachmentsForTask": "There are no attachments for this task.",
"AssigneeRequired": "Assignee is required", "AssigneeRequired": "Assignee is required",
"More": "Options", "More": "Options",

View File

@ -38,6 +38,7 @@
"@anticrm/contact": "~0.6.2", "@anticrm/contact": "~0.6.2",
"@anticrm/core": "~0.6.11", "@anticrm/core": "~0.6.11",
"@anticrm/chunter": "~0.6.1", "@anticrm/chunter": "~0.6.1",
"@anticrm/attachment": "~0.6.0",
"@anticrm/panel": "~0.6.0", "@anticrm/panel": "~0.6.0",
"@anticrm/view": "~0.6.0", "@anticrm/view": "~0.6.0",
"@anticrm/view-resources": "~0.6.0", "@anticrm/view-resources": "~0.6.0",

View File

@ -17,11 +17,11 @@
import { Panel } from '@anticrm/panel' import { Panel } from '@anticrm/panel'
import { createQuery, getClient } from '@anticrm/presentation' import { createQuery, getClient } from '@anticrm/presentation'
import type { Task } from '@anticrm/task' import type { Task } from '@anticrm/task'
import { EditBox, Grid } from '@anticrm/ui' import { Component, EditBox, Grid } from '@anticrm/ui'
import view from '@anticrm/view' import view from '@anticrm/view'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import task from '../plugin' import task from '../plugin'
import Attachments from './Attachments.svelte' import attachment from '@anticrm/attachment'
import TaskHeader from './TaskHeader.svelte' import TaskHeader from './TaskHeader.svelte'
export let _id: Ref<Task> export let _id: Ref<Task>
@ -72,7 +72,7 @@
</Grid> </Grid>
<div class="mt-14"> <div class="mt-14">
<Attachments objectId={object._id} _class={object._class} space={object.space} /> <Component is={attachment.component.Attachments} props={{ objectId: object._id, _class:object._class, space: object.space, noLabel: task.string.NoAttachmentsForTask }} />
</div> </div>
</Panel> </Panel>
{/if} {/if}

View File

@ -33,7 +33,6 @@ export default mergeIds(taskId, task, {
TaskUnAssign: '' as IntlString, TaskUnAssign: '' as IntlString,
TaskDescription: '' as IntlString, TaskDescription: '' as IntlString,
NoAttachmentsForTask: '' as IntlString, NoAttachmentsForTask: '' as IntlString,
UploadDropFilesHere: '' as IntlString,
More: '' as IntlString More: '' as IntlString
}, },
status: { status: {

View File

@ -866,5 +866,25 @@
"projectFolder": "plugins/devmodel", "projectFolder": "plugins/devmodel",
"shouldPublish": true "shouldPublish": true
}, },
{
"packageName": "@anticrm/attachment",
"projectFolder": "plugins/attachment",
"shouldPublish": true
},
{
"packageName": "@anticrm/attachment-assets",
"projectFolder": "plugins/attachment-assets",
"shouldPublish": true
},
{
"packageName": "@anticrm/attachment-resources",
"projectFolder": "plugins/attachment-resources",
"shouldPublish": true
},
{
"packageName": "@anticrm/model-attachment",
"projectFolder": "models/attachment",
"shouldPublish": true
}
] ]
} }

View File

@ -45,7 +45,7 @@
"@anticrm/elastic": "~0.6.0", "@anticrm/elastic": "~0.6.0",
"jwt-simple": "^0.5.6", "jwt-simple": "^0.5.6",
"@anticrm/server-core": "~0.6.1", "@anticrm/server-core": "~0.6.1",
"@anticrm/chunter": "~0.6.0", "@anticrm/attachment": "~0.6.0",
"@anticrm/contrib": "~0.6.0", "@anticrm/contrib": "~0.6.0",
"minio": "^7.0.19" "minio": "^7.0.19"
} }

View File

@ -26,7 +26,7 @@ import { Space, Ref, Doc, Account, generateId } from '@anticrm/core'
// import { TxFactory } from '@anticrm/core' // import { TxFactory } from '@anticrm/core'
import type { Token, IndexedDoc } from '@anticrm/server-core' import type { Token, IndexedDoc } from '@anticrm/server-core'
import { createElasticAdapter } from '@anticrm/elastic' import { createElasticAdapter } from '@anticrm/elastic'
import chunter from '@anticrm/chunter' import attachment from '@anticrm/attachment'
// import { createContributingClient } from '@anticrm/contrib' // import { createContributingClient } from '@anticrm/contrib'
import { Client, ItemBucketMetadata } from 'minio' import { Client, ItemBucketMetadata } from 'minio'
@ -179,7 +179,7 @@ export function start (config: { transactorEndpoint: string, elasticUrl: string,
const indexedDoc: IndexedDoc = { const indexedDoc: IndexedDoc = {
id: generateId() + '/attachments/' + name, id: generateId() + '/attachments/' + name,
_class: chunter.class.Attachment, _class: attachment.class.Attachment,
space, space,
modifiedOn: Date.now(), modifiedOn: Date.now(),
modifiedBy: 'core:account:System' as Ref<Account>, modifiedBy: 'core:account:System' as Ref<Account>,
@ -250,7 +250,7 @@ export function start (config: { transactorEndpoint: string, elasticUrl: string,
const indexedDoc: IndexedDoc = { const indexedDoc: IndexedDoc = {
id: generateId() + '/attachments/' + 'Profile.pdf', id: generateId() + '/attachments/' + 'Profile.pdf',
_class: chunter.class.Attachment, _class: attachment.class.Attachment,
space, space,
modifiedOn: Date.now(), modifiedOn: Date.now(),
modifiedBy: 'core:account:System' as Ref<Account>, modifiedBy: 'core:account:System' as Ref<Account>,

View File

@ -46,7 +46,7 @@
"@anticrm/elastic": "~0.6.0", "@anticrm/elastic": "~0.6.0",
"jwt-simple": "^0.5.6", "jwt-simple": "^0.5.6",
"@anticrm/server-core": "~0.6.1", "@anticrm/server-core": "~0.6.1",
"@anticrm/chunter": "~0.6.0", "@anticrm/attachment": "~0.6.0",
"@anticrm/core": "~0.6.11", "@anticrm/core": "~0.6.11",
"@anticrm/contrib": "~0.6.0", "@anticrm/contrib": "~0.6.0",
"minio": "^7.0.19" "minio": "^7.0.19"

View File

@ -24,7 +24,7 @@ import { Space, Ref, Doc, Account, generateId } from '@anticrm/core'
// import { TxFactory } from '@anticrm/core' // import { TxFactory } from '@anticrm/core'
import type { Token, IndexedDoc } from '@anticrm/server-core' import type { Token, IndexedDoc } from '@anticrm/server-core'
import { createElasticAdapter } from '@anticrm/elastic' import { createElasticAdapter } from '@anticrm/elastic'
import chunter from '@anticrm/chunter' import attachment from '@anticrm/attachment'
// import { createContributingClient } from '@anticrm/contrib' // import { createContributingClient } from '@anticrm/contrib'
import { Client, ItemBucketMetadata } from 'minio' import { Client, ItemBucketMetadata } from 'minio'
@ -160,7 +160,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
const indexedDoc: IndexedDoc = { const indexedDoc: IndexedDoc = {
id: generateId() + '/attachments/' + name, id: generateId() + '/attachments/' + name,
_class: chunter.class.Attachment, _class: attachment.class.Attachment,
space, space,
modifiedOn: Date.now(), modifiedOn: Date.now(),
modifiedBy: 'core:account:System' as Ref<Account>, modifiedBy: 'core:account:System' as Ref<Account>,