Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/IRIS-2582-tag-management' into r…
Browse files Browse the repository at this point in the history
…efactor/clean-fetch
  • Loading branch information
zovomat committed Mar 16, 2022
2 parents 99c93d3 + f6673b7 commit 5b6241a
Show file tree
Hide file tree
Showing 17 changed files with 194 additions and 25 deletions.
11 changes: 6 additions & 5 deletions src/boot/app/app-loader-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@ import {
getUserAccount,
getUserAccounts,
getUserSettings,
getTags,
useUserAccount,
useUserAccounts,
useUserSettings,
useTags,
useUserRight,
useUserRights,
getUserRight,
getUserRights,
useAccountStore
getUserRights
} from '../../store/account';
import { useIsMobile } from '../../shell/hooks';
import {
Expand All @@ -43,7 +40,7 @@ import {
useIntegratedFunction,
useIntegratedHook
} from '../../store/integrations/hooks';
import { CarbonioModule, useNotify, useRefresh } from '../../../types';
import { CarbonioModule } from '../../../types';
import {
usePushHistoryCallback,
useGoBackHistoryCallback,
Expand All @@ -61,6 +58,8 @@ import {
useUpdateCurrentBoard
} from '../../shell/boards/board-hooks';
import { getSoapFetch, getXmlSoapFetch } from '../../network/fetch';
import { getTag, getTags, useTag, useTags } from '../../store/tags';
import { useNotify, useRefresh } from '../../store/network';

// eslint-disable-next-line @typescript-eslint/ban-types
export const getAppFunctions = (pkg: CarbonioModule): Record<string, Function> => ({
Expand Down Expand Up @@ -101,6 +100,8 @@ export const getAppFunctions = (pkg: CarbonioModule): Record<string, Function> =
getUserRights,
useTags,
getTags,
useTag,
getTag,
useNotify,
useRefresh,
// BOARDS
Expand Down
8 changes: 4 additions & 4 deletions src/network/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

import { find } from 'lodash';
import { goToLogin } from './go-to-login';
import { Account, ErrorSoapResponse, SoapResponse, SuccessSoapResponse, Tag } from '../../types';
import { Account, ErrorSoapResponse, SoapResponse, SuccessSoapResponse } from '../../types';
import { userAgent } from './user-agent';
import { report } from '../reporting';
import { useAccountStore } from '../store/account';
import { SHELL_APP_ID } from '../constants';
import { useNetworkStore } from '../store/network';
import { handleTagSync } from '../store/tags';

export const noOp = (): void => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
Expand Down Expand Up @@ -74,7 +75,7 @@ const getXmlSession = (context?: any): string => {

const handleResponse = <R>(api: string, res: SoapResponse<R>): R => {
const { pollingInterval, context } = useNetworkStore.getState();
const { tags, usedQuota } = useAccountStore.getState();
const { usedQuota } = useAccountStore.getState();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
clearTimeout(get().noOpTimeout);
Expand All @@ -96,9 +97,8 @@ const handleResponse = <R>(api: string, res: SoapResponse<R>): R => {
if (res?.Header?.context) {
const responseUsedQuota =
res.Header.context?.refresh?.mbx?.[0]?.s ?? res.Header.context?.notify?.[0]?.mbx?.[0]?.s;
const responseTags = res.Header.context?.refresh?.tags?.tag as Array<Tag>;
handleTagSync(res.Header.context);
useAccountStore.setState({
tags: responseTags ?? tags,
usedQuota: responseUsedQuota ?? usedQuota
});
useNetworkStore.setState({
Expand Down
2 changes: 1 addition & 1 deletion src/network/get-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { filter } from 'lodash';
import { SHELL_APP_ID, SHELL_MODES } from '../constants';
import { useAppStore } from '../store/app';
import { normalizeAccount } from '../store/account/normalization';
import { AccountSettings, AccountState, GetInfoResponse, Tag, CarbonioModule } from '../../types';
import { AccountSettings, AccountState, GetInfoResponse, CarbonioModule } from '../../types';
import { goToLogin } from './go-to-login';
import { isAdmin, isFullClient, isStandalone } from '../multimode';
import { getSoapFetch } from './fetch';
Expand Down
60 changes: 60 additions & 0 deletions src/network/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import produce from 'immer';
import {
CreateTagRequest,
CreateTagResponse,
TagActionRequest,
TagActionResponse
} from '../../types';
import { Tag } from '../../types/tags';
import { SHELL_APP_ID } from '../constants';
import { useTagStore } from '../store/tags';
import { getSoapFetch } from './fetch';

const set = useTagStore.setState;
export const createTag = (tag: Omit<Tag, 'id'>): Promise<string> =>
getSoapFetch(SHELL_APP_ID)<CreateTagRequest, CreateTagResponse>('CreateTag', {
_jsns: 'urn:zimbraMail',
tag
}).then((r: CreateTagResponse) => {
set((state) => ({ tags: { ...state.tags, [r.tag[0].id]: r.tag[0] } }));
return r.tag[0].id;
});

export const deleteTag = (id: string): Promise<TagActionResponse> =>
getSoapFetch(SHELL_APP_ID)<TagActionRequest, TagActionResponse>('TagAction', {
_jsns: 'urn:zimbraMail',
action: { op: 'delete', id }
});

export const renameTag = (id: string, name: string): Promise<void> =>
getSoapFetch(SHELL_APP_ID)<TagActionRequest, TagActionResponse>('TagAction', {
_jsns: 'urn:zimbraMail',
action: { op: 'rename', id, name }
}).then((r: TagActionResponse) => {
set(
produce((state) => {
state.tags[id].name = name;
})
);
});
export const changeTagColor = (id: string, color: string | number): Promise<void> =>
getSoapFetch(SHELL_APP_ID)<TagActionRequest, TagActionResponse>('TagAction', {
_jsns: 'urn:zimbraMail',
action: typeof color === 'number' ? { op: 'color', color, id } : { op: 'color', rgb: color, id }
}).then((r: TagActionResponse) => {
set(
produce((state) => {
if (color === 'number') {
state.tags[id].color = color;
} else {
state.tags[id].rgb = color;
}
})
);
});
3 changes: 3 additions & 0 deletions src/shell/shell-view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ThemeCallbacksContext } from '../boot/theme-provider';
import { useUserSettings } from '../store/account';
import { ShellUtilityBar, ShellUtilityPanel } from '../utility-bar';
import { useCurrentRoute } from '../history/hooks';
import { useTagStore } from '../store/tags/store';

const Background = styled.div`
background: ${({ theme }) => theme.palette.gray6.regular};
Expand Down Expand Up @@ -44,6 +45,8 @@ function DarkReaderListener() {
export function Shell() {
const [mobileNavOpen, setMobileNavOpen] = useState(false);
const activeRoute = useCurrentRoute();
const tagStore = useTagStore();
console.log('@@ tagStore', tagStore);

return (
<Background>
Expand Down
7 changes: 3 additions & 4 deletions src/store/account/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
AccountRightName,
AccountRights,
AccountRightTarget,
AccountSettings,
Tag
AccountSettings
} from '../../../types';
import { useAccountStore } from './store';

Expand All @@ -35,7 +34,7 @@ export const useUserRight = (right: AccountRightName): Array<AccountRightTarget>
export const useUserSettings = (): AccountSettings => useAccountStore((s) => s.settings);
export const useUserSetting = <T = void>(...path: Array<string>): string | T =>
useAccountStore((s) => get(s.settings, join(path, '.')));
export const useTags = (): Array<Tag> => useAccountStore((s) => s.tags);
// @@ export const useTags = (): Array<Tag> => useAccountStore((s) => s.tags);

export const getUserAccount = (): Account => useAccountStore.getState().account as Account;
export const getUserAccounts = (): Array<Account> => [
Expand All @@ -44,7 +43,7 @@ export const getUserAccounts = (): Array<Account> => [
export const getUserSettings = (): AccountSettings => useAccountStore.getState().settings;
export const getUserSetting = <T = void>(...path: Array<string>): string | T =>
get(useAccountStore.getState().settings, join(path, '.'));
export const getTags = (): Array<Tag> => useAccountStore.getState().tags;
// @@ export const getTags = (): Array<Tag> => useAccountStore.getState().tags;

export const getUserRights = (): AccountRights =>
useAccountStore.getState().account?.rights ?? { targets: [] };
Expand Down
1 change: 1 addition & 0 deletions src/store/network/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*/

export * from './store';
export * from './hooks';
16 changes: 16 additions & 0 deletions src/store/tags/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { Tag, Tags } from '../../../types';
import { useTagStore } from './store';

/* eslint-disable react-hooks/rules-of-hooks */
/* THIS FILE CONTAINS HOOKS, BUT ESLINT IS DUMB */

export const useTag = (id: string): Tag => useTagStore((s) => s.tags[id]);
export const getTag = (id: string): Tag => useTagStore.getState().tags[id];
export const useTags = (): Tags => useTagStore((s) => s.tags);
export const getTags = (): Tags => useTagStore.getState().tags;
9 changes: 9 additions & 0 deletions src/store/tags/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

export * from './hooks';
export * from './store';
export * from './sync';
12 changes: 12 additions & 0 deletions src/store/tags/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import create, { StoreApi, UseBoundStore } from 'zustand';
import { TagState } from '../../../types';

export const useTagStore = create<TagState>(() => ({
tags: {}
})) as UseBoundStore<TagState, StoreApi<TagState>>;
28 changes: 28 additions & 0 deletions src/store/tags/sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { reduce } from 'lodash';
import { SoapContext, Tag, Tags } from '../../../types';
import { useTagStore } from './store';

export const handleTagSync = (context: SoapContext): void => {
if (context.refresh?.tags?.tag) {
useTagStore.setState({
tags: reduce(
context.refresh.tags?.tag,
(acc: Tags, val: Tag): Tags => {
// eslint-disable-next-line no-param-reassign
acc[val.id] = val;
return acc;
},
{}
)
});
}
if (context.notify) {
console.log(context.notify);
}
};
1 change: 1 addition & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"unsaved_changes": "You have unsaved changes",
"unsaved_changes_line1": "Are you sure you want to leave this page without saving?",
"unsaved_changes_line2": "All your unsaved changes will be lost",
"update_view": "Update view",
"use_persona": "Use this persona",
"use_personas_line1": "Use personas to quickly change many settings when sending e-mail messages.",
"use_personas_line2": "For example, if you sometimes send e-mails in a particular role at work, create a persona for that.",
Expand Down
9 changes: 1 addition & 8 deletions types/account/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Tag } from '../tags';

export type ZimletProp = {
name: string;
Expand All @@ -20,7 +21,6 @@ export type AccountState = {
account?: Account;
settings: AccountSettings;
zimbraVersion: string;
tags: Array<Tag>;
usedQuota: number;
};

Expand All @@ -40,13 +40,6 @@ export type DelegateProps = {
right: string;
};

export type Tag = {
color?: string;
id: string;
name: string;
rgb?: string;
};

export type AccountSettings = {
attrs: Record<string, string | number>;
prefs: Record<string, string | number>;
Expand Down
6 changes: 3 additions & 3 deletions types/exports/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import { ActionFactory, AnyFunction, CombinedActionFactory, Action } from '../integrations';
import {
AccountSettings,
Tag,
// @@ Tag,
Account,
NotifyObject,
AccountRights,
Expand Down Expand Up @@ -93,8 +93,8 @@ export const getUserAccount: () => Account;
export const getUserAccounts: () => Array<Account>;
export const getUserRights: () => AccountRights;
export const getUserRight: (right: AccountRightName) => Array<AccountRightTarget>;
export const useTags: () => Array<Tag>;
export const getTags: () => Array<Tag>;
// @@ export const useTags: () => Array<Tag>;
// @@ export const getTags: () => Array<Tag>;
export const useUserSettings: () => AccountSettings;
export const useUserSetting: <T = void>(...path: Array<string>) => string | T;
export const getUserSettings: () => AccountSettings;
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './integrations';
export * from './theme';
export * from './search';
export * from './misc';
export * from './tags';
26 changes: 26 additions & 0 deletions types/network/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { AccountRights, ZimletProp } from '../account';
import { Tag } from '../tags';

export type ZimletPkgDescription = {
zimlet: Array<{
Expand Down Expand Up @@ -136,10 +137,35 @@ export type NotifyObject = {
version?: string;
mbx?: [{ s: number }];
folder?: Array<unknown>;
tags?: { tag: Array<Tag> };
};

export type NetworkState = {
noOpTimeout: unknown;
context: SoapContext;
pollingInterval: number;
};

export type CreateTagRequest = {
tag: Omit<Tag, id>;
_jsns: string;
};

export type CreateTagResponse = {
tag: [Tag];
};

export type TagActionRequest = {
_jsns: string;
action: {
op: 'rename' | 'color' | 'delete' | 'update';
id: string;
name?: string;
color?: number;
rgb?: string;
};
};
export type TagActionResponse = {
action: { op: string; id: string };
_jsns: string;
};
19 changes: 19 additions & 0 deletions types/tags/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable @typescript-eslint/ban-types */
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

export type Tag = {
color?: string;
id: string;
name: string;
rgb?: string;
};

export type Tags = Record<string, Tag>;

export type TagState = {
tags: Tags;
};

0 comments on commit 5b6241a

Please sign in to comment.