diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5d990a7d72..0d86d27644 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -31,6 +31,9 @@ specifiers: '@rush-temp/elastic': file:./projects/elastic.tgz '@rush-temp/front': file:./projects/front.tgz '@rush-temp/generator': file:./projects/generator.tgz + '@rush-temp/gmail': file:./projects/gmail.tgz + '@rush-temp/gmail-assets': file:./projects/gmail-assets.tgz + '@rush-temp/gmail-resources': file:./projects/gmail-resources.tgz '@rush-temp/lead': file:./projects/lead.tgz '@rush-temp/lead-assets': file:./projects/lead-assets.tgz '@rush-temp/lead-resources': file:./projects/lead-resources.tgz @@ -45,6 +48,7 @@ specifiers: '@rush-temp/model-contact': file:./projects/model-contact.tgz '@rush-temp/model-core': file:./projects/model-core.tgz '@rush-temp/model-demo': file:./projects/model-demo.tgz + '@rush-temp/model-gmail': file:./projects/model-gmail.tgz '@rush-temp/model-lead': file:./projects/model-lead.tgz '@rush-temp/model-recruit': file:./projects/model-recruit.tgz '@rush-temp/model-rig': file:./projects/model-rig.tgz @@ -204,6 +208,9 @@ dependencies: '@rush-temp/elastic': file:projects/elastic.tgz '@rush-temp/front': file:projects/front.tgz '@rush-temp/generator': file:projects/generator.tgz + '@rush-temp/gmail': file:projects/gmail.tgz + '@rush-temp/gmail-assets': file:projects/gmail-assets.tgz + '@rush-temp/gmail-resources': file:projects/gmail-resources.tgz_096c09b0b673a57c275d9767a12070b1 '@rush-temp/lead': file:projects/lead.tgz '@rush-temp/lead-assets': file:projects/lead-assets.tgz '@rush-temp/lead-resources': file:projects/lead-resources.tgz_096c09b0b673a57c275d9767a12070b1 @@ -218,6 +225,7 @@ dependencies: '@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.5.4 '@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.5.4 '@rush-temp/model-demo': file:projects/model-demo.tgz_typescript@4.5.4 + '@rush-temp/model-gmail': file:projects/model-gmail.tgz_typescript@4.5.4 '@rush-temp/model-lead': file:projects/model-lead.tgz_typescript@4.5.4 '@rush-temp/model-recruit': file:projects/model-recruit.tgz_typescript@4.5.4 '@rush-temp/model-rig': file:projects/model-rig.tgz_37f79b97d0d86442e45d380c86f520c5 @@ -11273,6 +11281,82 @@ packages: - utf-8-validate dev: false + file:projects/gmail-assets.tgz: + resolution: {integrity: sha512-yvZyg36xh0IBxOyVTbHZUZ7BiJLCsBaiC/Djvrc+/t5x068o3Na4ncoQAVRuVGF4z1RGRxD8Ystf2lwsevvArg==, tarball: file:projects/gmail-assets.tgz} + name: '@rush-temp/gmail-assets' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.41.8 + '@types/heft-jest': 1.0.2 + '@types/node': 16.11.14 + '@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237 + '@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4 + eslint: 7.32.0 + eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a + eslint-plugin-import: 2.25.3_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 5.2.0_eslint@7.32.0 + prettier: 2.5.1 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: false + + file:projects/gmail-resources.tgz_096c09b0b673a57c275d9767a12070b1: + resolution: {integrity: sha512-zZWhkD/HZH3/ljH7WhD2IG9NhQ6b1JPTgG2Rc35pGwScC2uzyI8xT3cq4K/jbsYLZ3BXj31BYOno7Mqo6pFcZg==, tarball: file:projects/gmail-resources.tgz} + id: file:projects/gmail-resources.tgz + name: '@rush-temp/gmail-resources' + version: 0.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237 + '@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4 + eslint: 7.32.0 + eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a + eslint-plugin-import: 2.25.3_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 5.2.0_eslint@7.32.0 + eslint-plugin-svelte3: 3.2.1_eslint@7.32.0+svelte@3.44.3 + prettier: 2.5.1 + prettier-plugin-svelte: 2.5.1_prettier@2.5.1+svelte@3.44.3 + sass: 1.45.0 + svelte: 3.44.3 + svelte-check: 2.2.11_4374c622c67ed7479ff0e44c29d09bce + svelte-loader: 3.1.2_svelte@3.44.3 + svelte-preprocess: 4.10.1_14d64cad431e31f100de7363af24a44f + typescript: 4.5.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - node-sass + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + dev: false + + file:projects/gmail.tgz: + resolution: {integrity: sha512-56FU7r/ypcn+MoC5NDXlSBgUcpB6Qr533YRbaAysYKoojaRu2/AkTIrldSXuS5cJCWjKqDBG2t251e+rsHm/fQ==, tarball: file:projects/gmail.tgz} + name: '@rush-temp/gmail' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.41.8 + '@types/heft-jest': 1.0.2 + '@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237 + '@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4 + eslint: 7.32.0 + eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a + eslint-plugin-import: 2.25.3_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 5.2.0_eslint@7.32.0 + prettier: 2.5.1 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: false + file:projects/lead-assets.tgz: resolution: {integrity: sha512-cRYB8PutP6HmaJjoEMLIEyMQEhKAQaCu0w2NJMF5TUW9vokia/22TXsHo1+xEGI1rx2epywbGXet/fL40tdbDw==, tarball: file:projects/lead-assets.tgz} name: '@rush-temp/lead-assets' @@ -11417,7 +11501,7 @@ packages: dev: false file:projects/model-all.tgz_typescript@4.5.4: - resolution: {integrity: sha512-iCugm1e/KTBXZ0FNnog/eP07l49sFIDU2orN0vAMUJ5pgZC7T38LSjnOL2y80OmoTbQK/3G2eH7Or+bxOYk2Cg==, tarball: file:projects/model-all.tgz} + resolution: {integrity: sha512-oKPQz2zoE53ROTtb76Vp43+PatfI+CKrdq0sUleUVaKPfWw74BKTXmqSAkZU1PVnr/DaKY/Gnl9Eo9JrXOUiig==, tarball: file:projects/model-all.tgz} id: file:projects/model-all.tgz name: '@rush-temp/model-all' version: 0.0.0 @@ -11546,6 +11630,27 @@ packages: - typescript dev: false + file:projects/model-gmail.tgz_typescript@4.5.4: + resolution: {integrity: sha512-c7TM2OxH/Xp/6Il6K2obdrOpl0CVmj7z1FTu94EVLYY6ZNICX184K4kegYm39FrigozEFQLORjaZCV9vRnbx1g==, tarball: file:projects/model-gmail.tgz} + id: file:projects/model-gmail.tgz + name: '@rush-temp/model-gmail' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.41.8 + '@types/heft-jest': 1.0.2 + '@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237 + '@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4 + eslint: 7.32.0 + eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a + eslint-plugin-import: 2.25.3_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 5.2.0_eslint@7.32.0 + prettier: 2.5.1 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + file:projects/model-lead.tgz_typescript@4.5.4: resolution: {integrity: sha512-3+Wf+/TdMpbuSoiTaI/ga+1KHSsPd1q9MDtpG6i4oAhxt/48aTZnfOV4nt9hrpWy2MmQWVhK9YJFTaKGIgKwOA==, tarball: file:projects/model-lead.tgz} id: file:projects/model-lead.tgz @@ -11930,7 +12035,7 @@ packages: dev: false file:projects/presentation.tgz_096c09b0b673a57c275d9767a12070b1: - resolution: {integrity: sha512-KbCYAGG7rz+Ov6f0yICsx0yzzufqd0RcVJ6XVLzYxLTurJiTeYNYSthU045vLXkRURpz4gEICQ0RHv9dvckMMA==, tarball: file:projects/presentation.tgz} + resolution: {integrity: sha512-tpa5gk8H/quPYXkpBhp5jS0bp/E+Jk7mTGhfE54q4RTr5LOYGTCg2HKmxZWqRV1N3g1Jk7nKAZHWMxMSGHCuKw==, tarball: file:projects/presentation.tgz} id: file:projects/presentation.tgz name: '@rush-temp/presentation' version: 0.0.0 @@ -11966,7 +12071,7 @@ packages: dev: false file:projects/prod.tgz_sass@1.45.0+typescript@4.5.4: - resolution: {integrity: sha512-cWieTfrEsukKvJvSGr/ZOX6Vo4aZQHGDpOrE2smLt21Rk+/lSNpUcpAKKGRoFmW08sWkQoYrU6BdPMgw4+/UNQ==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-XgKxpfDD6oNTIijCj64CrOXM6sYgZhDuDoy5wWIrr/4Y5QFn7TWpOnSjIgmIXMtLUCGk4L55CAZBK+okRGX25Q==, tarball: file:projects/prod.tgz} id: file:projects/prod.tgz name: '@rush-temp/prod' version: 0.0.0 @@ -12612,7 +12717,7 @@ packages: dev: false file:projects/view-resources.tgz_096c09b0b673a57c275d9767a12070b1: - resolution: {integrity: sha512-Ec9uQXBdFop5UPSMzA6UQaryHWmVTWVsDnWOzCH7BYtq7Zvw+763oJMFChaDsoGgeE2znn5zgam4sUn/1alqxQ==, tarball: file:projects/view-resources.tgz} + resolution: {integrity: sha512-oT79PCOUvwaL6QgjuwTNVJJqyE82WDmBx37jF5/c6SpSrYNF14+hN41rrPReKQyhhxkyrBts73IePyHxIn653Q==, tarball: file:projects/view-resources.tgz} id: file:projects/view-resources.tgz name: '@rush-temp/view-resources' version: 0.0.0 diff --git a/dev/prod/package.json b/dev/prod/package.json index ee9379e33d..7d23dd5ea3 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -85,6 +85,9 @@ "@anticrm/attachment-resources": "~0.6.0", "@anticrm/lead": "~0.6.0", "@anticrm/lead-assets": "~0.6.0", - "@anticrm/lead-resources": "~0.6.0" + "@anticrm/lead-resources": "~0.6.0", + "@anticrm/gmail": "~0.6.0", + "@anticrm/gmail-assets": "~0.6.0", + "@anticrm/gmail-resources": "~0.6.0" } } diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts index 14663a37ea..214aff867f 100644 --- a/dev/prod/src/platform.ts +++ b/dev/prod/src/platform.ts @@ -28,6 +28,7 @@ import { telegramId } from '@anticrm/telegram' import { attachmentId } from '@anticrm/attachment' import { leadId } from '@anticrm/lead' import { clientId } from '@anticrm/client' +import { gmailId } from '@anticrm/gmail' import '@anticrm/login-assets' import '@anticrm/task-assets' @@ -40,6 +41,7 @@ import '@anticrm/activity-assets' import '@anticrm/setting-assets' import '@anticrm/telegram-assets' import '@anticrm/lead-assets' +import '@anticrm/gmail-assets' import '@anticrm/workbench-assets' import { setMetadata } from '@anticrm/platform' @@ -52,6 +54,7 @@ export function configurePlatform() { }) }) setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086') + setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087') setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT) addLocation(clientId, () => import(/* webpackChunkName: "client" */ '@anticrm/client-resources')) @@ -67,4 +70,5 @@ export function configurePlatform() { addLocation(leadId, () => import(/* webpackChunkName: "lead" */ '@anticrm/lead-resources')) addLocation(telegramId, () => import(/* webpackChunkName: "telegram" */ '@anticrm/telegram-resources')) addLocation(attachmentId, () => import(/* webpackChunkName: "attachment" */ '@anticrm/attachment-resources')) + addLocation(gmailId, () => import(/* webpackChunkName: "gmail" */ '@anticrm/gmail-resources')) } diff --git a/models/all/package.json b/models/all/package.json index ed1bb5a3f7..51ec13ceb6 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -45,6 +45,7 @@ "@anticrm/model-server-recruit": "~0.6.0", "@anticrm/model-activity": "~0.6.0", "@anticrm/model-attachment": "~0.6.0", + "@anticrm/model-gmail": "~0.6.0", "@anticrm/core": "~0.6.13" } } diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 2b39253392..0d3b0929fe 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -26,6 +26,7 @@ import { createModel as settingModel } from '@anticrm/model-setting' import { createModel as telegramModel } from '@anticrm/model-telegram' import { createModel as attachmentModel } from '@anticrm/model-attachment' import { createModel as leadModel } from '@anticrm/model-lead' +import { createModel as gmailModel } from '@anticrm/model-gmail' import { createModel as serverCoreModel } from '@anticrm/model-server-core' import { createModel as serverChunterModel } from '@anticrm/model-server-chunter' @@ -48,6 +49,7 @@ recruitModel(builder) settingModel(builder) telegramModel(builder) leadModel(builder) +gmailModel(builder) serverCoreModel(builder) serverChunterModel(builder) diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index 5c05fcde6c..b634787e3d 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -190,17 +190,6 @@ export function createModel (builder: Builder): void { presenter: contact.component.ChannelsPresenter }) - builder.createDoc( - contact.class.ChannelProvider, - core.space.Model, - { - label: 'Email' as IntlString, - icon: contact.icon.Email, - placeholder: 'john.appleseed@apple.com' - }, - contact.channelProvider.Email - ) - builder.createDoc( contact.class.ChannelProvider, core.space.Model, diff --git a/models/gmail/.eslintrc.js b/models/gmail/.eslintrc.js new file mode 100644 index 0000000000..c3c2c49417 --- /dev/null +++ b/models/gmail/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@anticrm/model-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/gmail/.npmignore b/models/gmail/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/gmail/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/gmail/config/rig.json b/models/gmail/config/rig.json new file mode 100644 index 0000000000..e9a9ee9add --- /dev/null +++ b/models/gmail/config/rig.json @@ -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" +} diff --git a/models/gmail/package.json b/models/gmail/package.json new file mode 100644 index 0000000000..89cc376a85 --- /dev/null +++ b/models/gmail/package.json @@ -0,0 +1,39 @@ +{ + "name": "@anticrm/model-gmail", + "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/activity": "~0.6.0", + "@anticrm/model": "~0.6.0", + "@anticrm/core": "~0.6.0", + "@anticrm/platform": "~0.6.5", + "@anticrm/model-core": "~0.6.0", + "@anticrm/model-contact": "~0.6.1", + "@anticrm/gmail": "~0.6.0", + "@anticrm/gmail-resources": "~0.6.0", + "@anticrm/setting": "~0.6.0", + "@anticrm/ui": "~0.6.0" + } +} diff --git a/models/gmail/src/index.ts b/models/gmail/src/index.ts new file mode 100644 index 0000000000..b336f3a450 --- /dev/null +++ b/models/gmail/src/index.ts @@ -0,0 +1,124 @@ +// +// 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. +// + +import type { IntlString } from '@anticrm/platform' +import { Builder, Model, TypeString, Prop, ArrOf } from '@anticrm/model' +import core, { TAttachedDoc, TDoc } from '@anticrm/model-core' +import contact from '@anticrm/model-contact' +import gmail from './plugin' +import type { Message, SharedMessage, SharedMessages } from '@anticrm/gmail' +import type { Domain, Type } from '@anticrm/core' +import setting from '@anticrm/setting' +import activity from '@anticrm/activity' + +export const DOMAIN_GMAIL = 'gmail' as Domain + +function TypeSharedMessage (): Type { + return { _class: gmail.class.SharedMessage, label: 'Shared message' as IntlString } +} + +@Model(gmail.class.Message, core.class.Doc, DOMAIN_GMAIL) +export class TMessage extends TDoc implements Message { + @Prop(TypeString(), 'MessageID' as IntlString) + messageId!: string + + @Prop(TypeString(), 'ReplyTo' as IntlString) + replyTo?: string + + @Prop(TypeString(), 'From' as IntlString) + from!: string + + @Prop(TypeString(), 'To' as IntlString) + to!: string + + @Prop(TypeString(), 'Contact' as IntlString) + contact!: string + + @Prop(TypeString(), 'Subject' as IntlString) + subject!: string + + @Prop(TypeString(), 'Message' as IntlString) + content!: string + + @Prop(TypeString(), 'Message' as IntlString) + textContent!: string + + @Prop(ArrOf(TypeString()), 'Copy' as IntlString) + copy?: string[] +} + +@Model(gmail.class.SharedMessages, core.class.AttachedDoc, DOMAIN_GMAIL) +export class TSharedMessages extends TAttachedDoc implements SharedMessages { + @Prop(ArrOf(TypeSharedMessage()), 'Messages' as IntlString) + messages!: SharedMessage[] +} + +export function createModel (builder: Builder): void { + builder.createModel(TMessage, TSharedMessages) + + builder.createDoc( + contact.class.ChannelProvider, + core.space.Model, + { + label: 'Gmail' as IntlString, + icon: contact.icon.Email, + placeholder: 'john.appleseed@apple.com', + presenter: gmail.component.Main, + integrationType: gmail.integrationType.Gmail + }, + contact.channelProvider.Email + ) + + builder.createDoc( + setting.class.IntegrationType, + core.space.Model, + { + label: 'Gmail', + description: 'Use gmail integration' as IntlString, + icon: gmail.component.IconGmail, + createComponent: gmail.component.Connect, + onDisconnect: gmail.handler.DisconnectHandler + }, + gmail.integrationType.Gmail + ) + + builder.createDoc( + core.class.Space, + core.space.Model, + { + name: 'Gmail', + description: 'Space for all gmail messages', + private: false, + archived: false, + members: [] + }, + gmail.space.Gmail + ) + + builder.createDoc( + activity.class.TxViewlet, + core.space.Model, + { + objectClass: gmail.class.SharedMessages, + icon: contact.icon.Telegram, + txClass: core.class.TxCreateDoc, + component: gmail.activity.TxSharedCreate, + label: gmail.string.SharedMessages, + display: 'content' + }, + gmail.ids.TxSharedCreate + ) +} diff --git a/models/gmail/src/plugin.ts b/models/gmail/src/plugin.ts new file mode 100644 index 0000000000..d327f84a23 --- /dev/null +++ b/models/gmail/src/plugin.ts @@ -0,0 +1,34 @@ +// +// 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. +// + +import { Ref } from '@anticrm/core' +import { IntlString, mergeIds } from '@anticrm/platform' +import { gmailId } from '@anticrm/gmail' +import gmail from '@anticrm/gmail-resources/src/plugin' +import type { AnyComponent } from '@anticrm/ui' +import type { TxViewlet } from '@anticrm/activity' + +export default mergeIds(gmailId, gmail, { + string: { + SharedMessages: '' as IntlString + }, + ids: { + TxSharedCreate: '' as Ref + }, + activity: { + TxSharedCreate: '' as AnyComponent + } +}) diff --git a/models/gmail/tsconfig.json b/models/gmail/tsconfig.json new file mode 100644 index 0000000000..1d60db76b4 --- /dev/null +++ b/models/gmail/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./node_modules/@anticrm/model-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + } +} \ No newline at end of file diff --git a/models/setting/src/index.ts b/models/setting/src/index.ts index db8b9a7779..af47e7e157 100644 --- a/models/setting/src/index.ts +++ b/models/setting/src/index.ts @@ -90,12 +90,4 @@ export function createModel (builder: Builder): void { spaces: [] } }, setting.ids.SettingApp) - - builder.createDoc(setting.class.IntegrationType, core.space.Model, { - label: 'Email', - description: 'Use email integration' as IntlString, - icon: setting.component.IconGmail, - createComponent: setting.component.ConnectEmail, - onDisconnect: setting.handler.EmailDisconnectHandler - }) } diff --git a/packages/panel/src/components/Panel.svelte b/packages/panel/src/components/Panel.svelte index 6fe74cbd44..1f7d3f995d 100644 --- a/packages/panel/src/components/Panel.svelte +++ b/packages/panel/src/components/Panel.svelte @@ -98,6 +98,7 @@ .header { flex-shrink: 0; padding: 0 2rem 0 2.5rem; + min-height: 0; height: 4rem; color: var(--theme-content-accent-color); border-bottom: 1px solid var(--theme-zone-bg); @@ -107,6 +108,7 @@ flex-shrink: 0; padding: 0 2rem; height: 3.5rem; + min-height: 0; border-bottom: 1px solid var(--theme-zone-bg); } } @@ -128,6 +130,8 @@ .leftSection, .rightSection { flex-basis: 50%; + width: 50%; + min-height: 0; display: flex; flex-direction: column; } diff --git a/packages/presentation/src/components/PDFViewer.svelte b/packages/presentation/src/components/PDFViewer.svelte index b77db22596..edc2331167 100644 --- a/packages/presentation/src/components/PDFViewer.svelte +++ b/packages/presentation/src/components/PDFViewer.svelte @@ -14,9 +14,8 @@ --> + +
+ {#if selectable} +
+ {selected.size} +
+
+
+
+
+
+
+ {:else if enabled} +
+
+
Gmail
+
+
+
+
+ { + selectable = !selectable + }} + /> + {:else} +
+
+ {/if} +
+
+ + {#if messages} + + {/if} + +
+ + diff --git a/plugins/setting-resources/src/components/integrations/ConnectEmail.svelte b/plugins/gmail-resources/src/components/Connect.svelte similarity index 50% rename from plugins/setting-resources/src/components/integrations/ConnectEmail.svelte rename to plugins/gmail-resources/src/components/Connect.svelte index 2b546b80e8..c64910316f 100644 --- a/plugins/setting-resources/src/components/integrations/ConnectEmail.svelte +++ b/plugins/gmail-resources/src/components/Connect.svelte @@ -1,28 +1,52 @@
-
-
+
{ @@ -32,7 +56,12 @@
-
Not implemented yet
+
+
diff --git a/plugins/gmail-resources/src/components/FullMessage.svelte b/plugins/gmail-resources/src/components/FullMessage.svelte new file mode 100644 index 0000000000..ca80e715ae --- /dev/null +++ b/plugins/gmail-resources/src/components/FullMessage.svelte @@ -0,0 +1,97 @@ + + + +
+
{ + dispatch('close') + }} + > + +
+
+
{currentMessage.subject}
+
+
+
+
+
+
+
+
+ + diff --git a/plugins/gmail-resources/src/components/FullMessageContent.svelte b/plugins/gmail-resources/src/components/FullMessageContent.svelte new file mode 100644 index 0000000000..dd2959d796 --- /dev/null +++ b/plugins/gmail-resources/src/components/FullMessageContent.svelte @@ -0,0 +1,52 @@ + + + +
+ + diff --git a/plugins/gmail-resources/src/components/FullMessagePopup.svelte b/plugins/gmail-resources/src/components/FullMessagePopup.svelte new file mode 100644 index 0000000000..cb2e2345ef --- /dev/null +++ b/plugins/gmail-resources/src/components/FullMessagePopup.svelte @@ -0,0 +1,57 @@ + + + + + + diff --git a/plugins/gmail-resources/src/components/Main.svelte b/plugins/gmail-resources/src/components/Main.svelte new file mode 100644 index 0000000000..19bf9d8f24 --- /dev/null +++ b/plugins/gmail-resources/src/components/Main.svelte @@ -0,0 +1,48 @@ + + + +{#if contactString} + {#if newMessage} + + {:else if currentMessage} + + {:else} + + {/if} +{/if} diff --git a/plugins/gmail-resources/src/components/Message.svelte b/plugins/gmail-resources/src/components/Message.svelte new file mode 100644 index 0000000000..5ec44b9935 --- /dev/null +++ b/plugins/gmail-resources/src/components/Message.svelte @@ -0,0 +1,68 @@ + + + +
{ + dispatch('select', message) + }} +> + {#if selectable} +
+ {/if} +
+
+
From: {formatName(message.sender)}
+
{getTime(message.modifiedOn)}
+
+
+ {message.subject} +
+
+ {message.textContent} +
+
+
+ + diff --git a/plugins/gmail-resources/src/components/Messages.svelte b/plugins/gmail-resources/src/components/Messages.svelte new file mode 100644 index 0000000000..40949eb630 --- /dev/null +++ b/plugins/gmail-resources/src/components/Messages.svelte @@ -0,0 +1,56 @@ + + + + + {#if messages} + {#each messages as message (message._id)} + { + select(message._id) + }} + /> + {/each} + {/if} + diff --git a/plugins/gmail-resources/src/components/NewMessage.svelte b/plugins/gmail-resources/src/components/NewMessage.svelte new file mode 100644 index 0000000000..095123d7f2 --- /dev/null +++ b/plugins/gmail-resources/src/components/NewMessage.svelte @@ -0,0 +1,151 @@ + + + +
+
{ + dispatch('close') + }} + > + +
+
+
Gmail
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ + diff --git a/plugins/gmail-resources/src/components/SharedMessages.svelte b/plugins/gmail-resources/src/components/SharedMessages.svelte new file mode 100644 index 0000000000..a15ef98120 --- /dev/null +++ b/plugins/gmail-resources/src/components/SharedMessages.svelte @@ -0,0 +1,43 @@ + + + +
+ +
+ + diff --git a/plugins/gmail-resources/src/components/activity/TxSharedCreate.svelte b/plugins/gmail-resources/src/components/activity/TxSharedCreate.svelte new file mode 100644 index 0000000000..160134220d --- /dev/null +++ b/plugins/gmail-resources/src/components/activity/TxSharedCreate.svelte @@ -0,0 +1,25 @@ + + + + diff --git a/plugins/setting-resources/src/components/icons/Gmail.svelte b/plugins/gmail-resources/src/components/icons/GmailColor.svelte similarity index 99% rename from plugins/setting-resources/src/components/icons/Gmail.svelte rename to plugins/gmail-resources/src/components/icons/GmailColor.svelte index 69c5e18dff..c0cc4e78a1 100644 --- a/plugins/setting-resources/src/components/icons/Gmail.svelte +++ b/plugins/gmail-resources/src/components/icons/GmailColor.svelte @@ -1,15 +1,15 @@ diff --git a/plugins/gmail-resources/src/index.ts b/plugins/gmail-resources/src/index.ts new file mode 100644 index 0000000000..700d3c2a74 --- /dev/null +++ b/plugins/gmail-resources/src/index.ts @@ -0,0 +1,45 @@ +// +// 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. +// + +import { getMetadata, Resources } from '@anticrm/platform' +import login from '@anticrm/login' +import Main from './components/Main.svelte' +import Connect from './components/Connect.svelte' +import IconGmail from './components/icons/GmailColor.svelte' +import TxSharedCreate from './components/activity/TxSharedCreate.svelte' + +export default async (): Promise => ({ + component: { + Main, + Connect, + IconGmail + }, + activity: { + TxSharedCreate + }, + handler: { + DisconnectHandler: async () => { + const url = getMetadata(login.metadata.GmailUrl) ?? '' + await fetch(url + '/signout', { + method: 'GET', + headers: { + Authorization: 'Bearer ' + (getMetadata(login.metadata.LoginToken) ?? ''), + 'Content-Type': 'application/json' + } + }) + } + } +}) diff --git a/plugins/gmail-resources/src/plugin.ts b/plugins/gmail-resources/src/plugin.ts new file mode 100644 index 0000000000..a646984bfb --- /dev/null +++ b/plugins/gmail-resources/src/plugin.ts @@ -0,0 +1,39 @@ +// +// 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. +// + +import { IntlString, mergeIds } from '@anticrm/platform' + +import gmail, { gmailId } from '@anticrm/gmail' + +export default mergeIds(gmailId, gmail, { + string: { + From: '' as IntlString, + To: '' as IntlString, + Copy: '' as IntlString, + MessagesSelected: '' as IntlString, + PublishSelected: '' as IntlString, + YouAnd: '' as IntlString, + CreateMessage: '' as IntlString, + ShareMessages: '' as IntlString, + Connect: '' as IntlString, + RedirectGoogle: '' as IntlString, + ConnectGmai: '' as IntlString, + Reply: '' as IntlString, + Subject: '' as IntlString, + Send: '' as IntlString, + NewMessageTo: '' as IntlString + } +}) diff --git a/plugins/gmail-resources/src/utils.ts b/plugins/gmail-resources/src/utils.ts new file mode 100644 index 0000000000..187e6a1246 --- /dev/null +++ b/plugins/gmail-resources/src/utils.ts @@ -0,0 +1,35 @@ +export function getTime (time: number): string { + let options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric' } + if (!isCurrentYear(time)) { + options = { + year: '2-digit', + month: 'numeric', + day: 'numeric', + ...options + } + } else if (!isToday(time)) { + options = { + month: 'numeric', + day: 'numeric', + ...options + } + } + + return new Date(time).toLocaleString('default', options) +} + +export function isToday (time: number): boolean { + const current = new Date() + const target = new Date(time) + return ( + current.getDate() === target.getDate() && + current.getMonth() === target.getMonth() && + current.getFullYear() === target.getFullYear() + ) +} + +export function isCurrentYear (time: number): boolean { + const current = new Date() + const target = new Date(time) + return current.getFullYear() === target.getFullYear() +} diff --git a/plugins/gmail-resources/svelte.config.js b/plugins/gmail-resources/svelte.config.js new file mode 100644 index 0000000000..944a06f73e --- /dev/null +++ b/plugins/gmail-resources/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/plugins/gmail-resources/tsconfig.json b/plugins/gmail-resources/tsconfig.json new file mode 100644 index 0000000000..cabe5aefad --- /dev/null +++ b/plugins/gmail-resources/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "target": "esnext", + "module": "esnext", + "declaration": true, + "outDir": "./lib", + "strict": true, + "esModuleInterop": true, + "lib": [ + "esnext", + "dom" + ] + } +} \ No newline at end of file diff --git a/plugins/gmail/.eslintrc.js b/plugins/gmail/.eslintrc.js new file mode 100644 index 0000000000..5da5872d4a --- /dev/null +++ b/plugins/gmail/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/gmail/.npmignore b/plugins/gmail/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/plugins/gmail/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/plugins/gmail/config/rig.json b/plugins/gmail/config/rig.json new file mode 100644 index 0000000000..af1257a896 --- /dev/null +++ b/plugins/gmail/config/rig.json @@ -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" +} diff --git a/plugins/gmail/package.json b/plugins/gmail/package.json new file mode 100644 index 0000000000..4db2f68c78 --- /dev/null +++ b/plugins/gmail/package.json @@ -0,0 +1,35 @@ +{ + "name": "@anticrm/gmail", + "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/core": "~0.6.11", + "@anticrm/ui": "~0.6.0", + "@anticrm/contact": "~0.6.0", + "@anticrm/setting": "~0.6.0" + } +} diff --git a/plugins/gmail/src/index.ts b/plugins/gmail/src/index.ts new file mode 100644 index 0000000000..f1e2498636 --- /dev/null +++ b/plugins/gmail/src/index.ts @@ -0,0 +1,89 @@ +// +// 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 { plugin } from '@anticrm/platform' +import type { Plugin } from '@anticrm/platform' +import type { Doc, Ref, Class, Space, AttachedDoc } from '@anticrm/core' +import type { AnyComponent } from '@anticrm/ui' +import type { IntegrationType, Handler } from '@anticrm/setting' + +/** + * @public + */ +export interface Message extends NewMessage, Doc { + messageId: string + from: string + textContent: string + contact: string +} + +/** + * @public + */ +export interface NewMessage { + replyTo?: string + to: string + subject: string + content: string + copy?: string[] +} + +/** + * @public + */ +export interface SharedMessage extends Doc { + messageId: string + subject: string + content: string + sender: string + receiver: string + incoming: boolean + textContent: string + copy?: string[] +} + +/** + * @public + */ +export interface SharedMessages extends AttachedDoc { + messages: SharedMessage[] +} + +/** + * @public + */ +export const gmailId = 'gmail' as Plugin + +export default plugin(gmailId, { + component: { + Main: '' as AnyComponent, + Connect: '' as AnyComponent, + IconGmail: '' as AnyComponent + }, + integrationType: { + Gmail: '' as Ref + }, + handler: { + DisconnectHandler: '' as Handler + }, + class: { + Message: '' as Ref>, + SharedMessages: '' as Ref>, + SharedMessage: '' as Ref> + }, + space: { + Gmail: '' as Ref + } +}) diff --git a/plugins/gmail/tsconfig.json b/plugins/gmail/tsconfig.json new file mode 100644 index 0000000000..32045300ce --- /dev/null +++ b/plugins/gmail/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "lib": ["esnext", "dom"] + } +} \ No newline at end of file diff --git a/plugins/login/src/index.ts b/plugins/login/src/index.ts index dd35c38506..4dee473156 100644 --- a/plugins/login/src/index.ts +++ b/plugins/login/src/index.ts @@ -39,6 +39,7 @@ export default plugin(loginId, { AccountsUrl: '' as Asset, UploadUrl: '' as Asset, TelegramUrl: '' as Asset, + GmailUrl: '' as Asset, LoginToken: '' as Metadata, LoginEndpoint: '' as Metadata, LoginEmail: '' as Metadata, diff --git a/plugins/setting-resources/src/index.ts b/plugins/setting-resources/src/index.ts index dc324a3b30..e1c352a3fb 100644 --- a/plugins/setting-resources/src/index.ts +++ b/plugins/setting-resources/src/index.ts @@ -19,8 +19,6 @@ import ManageStatuses from './components/statuses/ManageStatuses.svelte' import Support from './components/Support.svelte' import Privacy from './components/Privacy.svelte' import Terms from './components/Terms.svelte' -import ConnectEmail from './components/integrations/ConnectEmail.svelte' -import IconGmail from './components/icons/Gmail.svelte' export default async () => ({ component: { @@ -29,11 +27,6 @@ export default async () => ({ Support, Privacy, Terms, - ConnectEmail, - IconGmail, ManageStatuses - }, - handler: { - EmailDisconnectHandler: async () => {} } }) diff --git a/plugins/setting/src/index.ts b/plugins/setting/src/index.ts index 145908fd54..da7df492d3 100644 --- a/plugins/setting/src/index.ts +++ b/plugins/setting/src/index.ts @@ -61,12 +61,7 @@ export default plugin(settingId, { ManageStatuses: '' as AnyComponent, Support: '' as AnyComponent, Privacy: '' as AnyComponent, - Terms: '' as AnyComponent, - ConnectEmail: '' as AnyComponent, - IconGmail: '' as AnyComponent - }, - handler: { - EmailDisconnectHandler: '' as Handler + Terms: '' as AnyComponent }, string: { Setting: '' as IntlString, diff --git a/plugins/telegram-resources/src/components/Chat.svelte b/plugins/telegram-resources/src/components/Chat.svelte index b48d420891..28c0e19f63 100644 --- a/plugins/telegram-resources/src/components/Chat.svelte +++ b/plugins/telegram-resources/src/components/Chat.svelte @@ -213,7 +213,7 @@ padding: 0 6rem 0 2.5rem; height: 4rem; color: var(--theme-content-accent-color); - border-bottom: 1px solid var(--theme-card-divider); + border-bottom: 1px solid var(--theme-zone-bg); .icon { margin-right: 1rem; diff --git a/plugins/telegram-resources/src/components/Connect.svelte b/plugins/telegram-resources/src/components/Connect.svelte index 9227065f4a..b6a7fc762e 100644 --- a/plugins/telegram-resources/src/components/Connect.svelte +++ b/plugins/telegram-resources/src/components/Connect.svelte @@ -119,7 +119,6 @@
-
diff --git a/rush.json b/rush.json index bc62aedc88..f06c3451c5 100644 --- a/rush.json +++ b/rush.json @@ -891,5 +891,25 @@ "projectFolder": "dev/generator", "shouldPublish": false }, + { + "packageName": "@anticrm/model-gmail", + "projectFolder": "models/gmail", + "shouldPublish": true + }, + { + "packageName": "@anticrm/gmail", + "projectFolder": "plugins/gmail", + "shouldPublish": true + }, + { + "packageName": "@anticrm/gmail-assets", + "projectFolder": "plugins/gmail-assets", + "shouldPublish": true + }, + { + "packageName": "@anticrm/gmail-resources", + "projectFolder": "plugins/gmail-resources", + "shouldPublish": true + }, ] }