diff --git a/models/setting/src/index.ts b/models/setting/src/index.ts index 8b22407b03..2e91940ff8 100644 --- a/models/setting/src/index.ts +++ b/models/setting/src/index.ts @@ -44,50 +44,67 @@ export class TIntegrationType extends TDoc implements IntegrationType { export function createModel (builder: Builder): void { builder.createModel(TIntegration, TIntegrationType) - builder.createDoc(workbench.class.Application, core.space.Model, { - label: setting.string.Setting, - icon: setting.icon.Setting, - hidden: true, - navigatorModel: { - specials: [ - { - id: 'setting', - label: setting.string.Setting, - icon: setting.icon.Setting, - component: setting.component.Setting - }, - { - id: 'integrations', - label: setting.string.Integrations, - icon: setting.icon.Integrations, - component: setting.component.Integrations - }, - { - id: 'statuses', - label: setting.string.ManageStatuses, - icon: task.icon.ManageStatuses, - component: setting.component.ManageStatuses - }, - { - id: 'support', - label: setting.string.Support, - icon: setting.icon.Support, - component: setting.component.Support - }, - { - id: 'privacy', - label: setting.string.Privacy, - icon: setting.icon.Privacy, - component: setting.component.Privacy - }, - { - id: 'terms', - label: setting.string.Terms, - icon: setting.icon.Terms, - component: setting.component.Terms - } - ], - spaces: [] - } - }, setting.ids.SettingApp) + builder.createDoc( + workbench.class.Application, + core.space.Model, + { + label: setting.string.Setting, + icon: setting.icon.Setting, + hidden: true, + navigatorModel: { + specials: [ + { + id: 'profile', + label: setting.string.EditProfile, + icon: setting.icon.EditProfile, + component: setting.component.Profile + }, + { + id: 'password', + label: setting.string.ChangePassword, + icon: setting.icon.Password, + component: setting.component.Password + }, + { + id: 'setting', + label: setting.string.Setting, + icon: setting.icon.Setting, + component: setting.component.Setting + }, + { + id: 'integrations', + label: setting.string.Integrations, + icon: setting.icon.Integrations, + component: setting.component.Integrations + }, + { + id: 'statuses', + label: setting.string.ManageStatuses, + icon: task.icon.ManageStatuses, + component: setting.component.ManageStatuses + }, + { + id: 'support', + label: setting.string.Support, + icon: setting.icon.Support, + component: setting.component.Support + }, + { + id: 'privacy', + label: setting.string.Privacy, + icon: setting.icon.Privacy, + component: setting.component.Privacy + }, + { + id: 'terms', + label: setting.string.Terms, + icon: setting.icon.Terms, + component: setting.component.Terms + } + ], + spaces: [] + } + }, + setting.ids.SettingApp + ) } diff --git a/packages/theme/styles/_layouts.scss b/packages/theme/styles/_layouts.scss index 2ecd601587..65e305d272 100644 --- a/packages/theme/styles/_layouts.scss +++ b/packages/theme/styles/_layouts.scss @@ -213,6 +213,7 @@ p:last-child { margin-block-end: 0; } .mt-3 { margin-top: .75rem; } .mt-4 { margin-top: 1rem; } .mt-5 { margin-top: 1.25rem; } +.mt-6 { margin-top: 1.5rem; } .mt-9 { margin-top: 2.25rem; } .mt-10 { margin-top: 2.5rem; } .mt-14 { margin-top: 3.5rem; } diff --git a/packages/ui/src/utils.ts b/packages/ui/src/utils.ts index d5ec8d570d..efa9921ee1 100644 --- a/packages/ui/src/utils.ts +++ b/packages/ui/src/utils.ts @@ -17,8 +17,12 @@ import { setMetadata } from '@anticrm/platform' import type { Metadata } from '@anticrm/platform' -export function setMetadataLocalStorage(id: Metadata, value: string): void { - localStorage.setItem(id, value) +export function setMetadataLocalStorage(id: Metadata, value: string | null): void { + if (value) { + localStorage.setItem(id, value) + } else { + localStorage.removeItem(id) + } setMetadata(id, value) } diff --git a/plugins/login-resources/src/index.ts b/plugins/login-resources/src/index.ts index cfbafec21d..bda0d59501 100644 --- a/plugins/login-resources/src/index.ts +++ b/plugins/login-resources/src/index.ts @@ -28,3 +28,5 @@ export default async () => ({ LoginApp } }) + +export * from './utils' diff --git a/plugins/login-resources/src/utils.ts b/plugins/login-resources/src/utils.ts index 98390220e9..16d9d0276f 100644 --- a/plugins/login-resources/src/utils.ts +++ b/plugins/login-resources/src/utils.ts @@ -163,12 +163,14 @@ export async function getWorkspaces (): Promise { if (overrideToken !== undefined) { const endpoint = getMetadata(login.metadata.OverrideEndpoint) if (endpoint !== undefined) { - return [{ - _id: '' as any, - workspace: 'DEV WORKSPACE', - organisation: '', - accounts: [] - }] + return [ + { + _id: '' as any, + workspace: 'DEV WORKSPACE', + organisation: '', + accounts: [] + } + ] } } @@ -361,3 +363,65 @@ export async function signUpJoin ( return [unknownError(err), undefined] } } + +export async function changeName (first: string, last: string): Promise { + const accountsUrl = getMetadata(login.metadata.AccountsUrl) + + if (accountsUrl === undefined) { + throw new Error('accounts url not specified') + } + + const overrideToken = getMetadata(login.metadata.OverrideLoginToken) + if (overrideToken !== undefined) { + const endpoint = getMetadata(login.metadata.OverrideEndpoint) + if (endpoint !== undefined) { + return + } + } + const token = fetchMetadataLocalStorage(login.metadata.LoginToken) as string + + const request: Request<[string, string]> = { + method: 'changeName', + params: [first, last] + } + + await fetch(accountsUrl, { + method: 'POST', + headers: { + Authorization: 'Bearer ' + token, + 'Content-Type': 'application/json' + }, + body: serialize(request) + }) +} + +export async function changePassword (oldPassword: string, password: string): Promise { + const accountsUrl = getMetadata(login.metadata.AccountsUrl) + + if (accountsUrl === undefined) { + throw new Error('accounts url not specified') + } + + const overrideToken = getMetadata(login.metadata.OverrideLoginToken) + if (overrideToken !== undefined) { + const endpoint = getMetadata(login.metadata.OverrideEndpoint) + if (endpoint !== undefined) { + return + } + } + const token = fetchMetadataLocalStorage(login.metadata.LoginToken) as string + + const request: Request<[string, string]> = { + method: 'changePassword', + params: [oldPassword, password] + } + + await fetch(accountsUrl, { + method: 'POST', + headers: { + Authorization: 'Bearer ' + token, + 'Content-Type': 'application/json' + }, + body: serialize(request) + }) +} diff --git a/plugins/setting-assets/assets/icons.svg b/plugins/setting-assets/assets/icons.svg index 70bab8b693..a404feea66 100644 --- a/plugins/setting-assets/assets/icons.svg +++ b/plugins/setting-assets/assets/icons.svg @@ -1,4 +1,13 @@ + + + + + + + + + diff --git a/plugins/setting-assets/lang/en.json b/plugins/setting-assets/lang/en.json index 6fd66054f6..9b7fefc651 100644 --- a/plugins/setting-assets/lang/en.json +++ b/plugins/setting-assets/lang/en.json @@ -6,12 +6,17 @@ "Support": "Support", "Privacy": "Privacy", "Terms": "Terms", - + "EditProfile": "Edit profile", "Folders": "Folders", "Templates": "Templates", "Delete": "Delete", - + "ChangePassword": "Change password", + "CurrentPassword": "Current password", + "NewPassword": "New password", "Disconnect": "Disconnect", + "Save": "Save", + "Saving": "Saving...", + "Saved": "Saved", "Add": "Add", "LearnMore": "Learn more" } diff --git a/plugins/setting-assets/src/index.ts b/plugins/setting-assets/src/index.ts index 274494bc3b..74fa51fbf4 100644 --- a/plugins/setting-assets/src/index.ts +++ b/plugins/setting-assets/src/index.ts @@ -18,6 +18,8 @@ import setting, { settingId } from '@anticrm/setting' const icons = require('../assets/icons.svg') loadMetadata(setting.icon, { + EditProfile: `${icons}#edit`, + Password: `${icons}#password`, Setting: `${icons}#settings`, Integrations: `${icons}#integration`, Support: `${icons}#support`, diff --git a/plugins/setting-resources/package.json b/plugins/setting-resources/package.json index 2e796a97b1..cfcf3c9c87 100644 --- a/plugins/setting-resources/package.json +++ b/plugins/setting-resources/package.json @@ -35,10 +35,13 @@ "@anticrm/core": "~0.6.11", "svelte": "^3.37.0", "@anticrm/setting": "~0.6.0", + "@anticrm/contact": "~0.6.2", + "@anticrm/attachment": "~0.6.0", "@anticrm/ui": "~0.6.0", "@anticrm/presentation": "~0.6.2", "@anticrm/view": "~0.6.0", "@anticrm/view-resources": "~0.6.0", + "@anticrm/login-resources": "~0.6.2", "@anticrm/task": "~0.6.0", "@anticrm/task-resources": "~0.6.0", "@anticrm/workbench": "~0.6.1" diff --git a/plugins/setting-resources/src/components/Password.svelte b/plugins/setting-resources/src/components/Password.svelte new file mode 100644 index 0000000000..90bd4f71af --- /dev/null +++ b/plugins/setting-resources/src/components/Password.svelte @@ -0,0 +1,105 @@ + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + diff --git a/plugins/setting-resources/src/components/Profile.svelte b/plugins/setting-resources/src/components/Profile.svelte new file mode 100644 index 0000000000..7ab23b0509 --- /dev/null +++ b/plugins/setting-resources/src/components/Profile.svelte @@ -0,0 +1,206 @@ + + + +
+
+
+
+
+ {#if employee} +
+
+ +
+
+
+
+ { + changeName(firstName, lastName) + }} + /> +
+
+ { + changeName(firstName, lastName) + }} + /> +
+
+ +
+
+ +
+ +
+
+ {#if !employee.channels || employee.channels.length === 0} + + showPopup( + contact.component.SocialEditor, + { values: employee?.channels ?? [] }, + ev.target, + (result) => { + saveChannels(result) + } + )} + /> + + {:else} + +
+ + showPopup( + contact.component.SocialEditor, + { values: employee?.channels ?? [] }, + ev.target, + (result) => { + saveChannels(result) + } + )} + /> +
+ {/if} +
+
+
+
+ {/if} +
+ + diff --git a/plugins/setting-resources/src/index.ts b/plugins/setting-resources/src/index.ts index e1c352a3fb..fde8444a39 100644 --- a/plugins/setting-resources/src/index.ts +++ b/plugins/setting-resources/src/index.ts @@ -13,6 +13,9 @@ // limitations under the License. // +import { Resources } from '@anticrm/platform' +import Profile from './components/Profile.svelte' +import Password from './components/Password.svelte' import Setting from './components/Setting.svelte' import Integrations from './components/Integrations.svelte' import ManageStatuses from './components/statuses/ManageStatuses.svelte' @@ -20,8 +23,10 @@ import Support from './components/Support.svelte' import Privacy from './components/Privacy.svelte' import Terms from './components/Terms.svelte' -export default async () => ({ +export default async (): Promise => ({ component: { + Profile, + Password, Setting, Integrations, Support, diff --git a/plugins/setting/src/index.ts b/plugins/setting/src/index.ts index bb85a009af..4b78f4f28e 100644 --- a/plugins/setting/src/index.ts +++ b/plugins/setting/src/index.ts @@ -56,6 +56,8 @@ export default plugin(settingId, { IntegrationType: '' as Ref> }, component: { + Profile: '' as AnyComponent, + Password: '' as AnyComponent, Setting: '' as AnyComponent, Integrations: '' as AnyComponent, ManageStatuses: '' as AnyComponent, @@ -75,9 +77,18 @@ export default plugin(settingId, { Delete: '' as IntlString, Disconnect: '' as IntlString, Add: '' as IntlString, - LearnMore: '' as IntlString + LearnMore: '' as IntlString, + EditProfile: '' as IntlString, + ChangePassword: '' as IntlString, + CurrentPassword: '' as IntlString, + NewPassword: '' as IntlString, + Save: '' as IntlString, + Saving: '' as IntlString, + Saved: '' as IntlString }, icon: { + EditProfile: '' as Asset, + Password: '' as Asset, Setting: '' as Asset, Integrations: '' as Asset, Support: '' as Asset, diff --git a/plugins/workbench-resources/src/components/AccountPopup.svelte b/plugins/workbench-resources/src/components/AccountPopup.svelte index 90df703831..465039a165 100644 --- a/plugins/workbench-resources/src/components/AccountPopup.svelte +++ b/plugins/workbench-resources/src/components/AccountPopup.svelte @@ -14,11 +14,13 @@ -->