Merge pull request #11000 from ToolJet/mail-css-bugs

Email Images and New Organization dropdown UI
This commit is contained in:
Adish M 2024-10-22 13:48:31 +05:30 committed by GitHub
commit 291a86ffe3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 155 additions and 64 deletions

View file

@ -1,52 +1,45 @@
import React, { useState } from 'react';
import Select from '@/_ui/Select';
import { components } from 'react-select';
import { EditOrganization } from './EditOrganization';
import { CreateOrganization } from './CreateOrganization';
import { useTranslation } from 'react-i18next';
import { authenticationService } from '@/_services';
import SolidIcon from '@/_ui/Icon/SolidIcons';
import { ToolTip } from '@/_components';
import { decodeEntities } from '@/_helpers/utils';
const Menu = (props) => {
const { t } = useTranslation();
const { admin } = authenticationService.currentSessionValue;
const darkMode = localStorage.getItem('darkMode') === 'true';
return (
<components.Menu {...props}>
<div className={darkMode && 'dark-theme'} style={{ padding: '4px' }}>
{admin && (
<>
<div
className="org-custom-select-header-wrap"
style={{ padding: '8px 12px' }}
onClick={() => props.selectProps.setShowEditOrg(true)}
>
<div className="row cursor-pointer d-flex align-items-center">
<div className="col-10">{props?.selectProps?.value?.label}</div>
<div className="col-1 tj-secondary-btn org-edit-icon">
<SolidIcon name="editrectangle" width="14" fill="#3E63DD" />
</div>
</div>
<div
className={`org-dropdown-shadow ${darkMode && 'dark-theme'}`}
style={{ paddingTop: '4px', paddingBottom: '4px' }}
>
<>
<div className="org-custom-select-header-wrap" style={{ padding: '8px 12px' }}>
<div className="row cursor-pointer d-flex align-items-center">
<div className="col-10 select-header-font">Workspaces ({props.options.length})</div>
{admin && (
<ToolTip message={'Add new workspace'} position="top">
<div className="col-1" style={{ paddingRight: '24px' }} onClick={props.selectProps.setShowCreateOrg}>
<SolidIcon
name="plus"
fill="var(--icon-strong)"
className=""
dataCy="add-new-workspace-link"
width="15"
/>
</div>
</ToolTip>
)}
</div>
</>
)}
<div className={`${darkMode && 'dark-theme'}`}>{props.children}</div>
<div
className="cursor-pointer d-flex align-items-center add-workspace-button"
style={{ padding: '4px 12px', color: '#3E63DD' }}
onClick={props.selectProps.setShowCreateOrg}
>
<div className="add-new-workspace-icon-old-wrap">
<SolidIcon name="plus" fill="#FDFDFE" className="add-new-workspace-icon-old" />
</div>
</>
<div className="add-new-workspace-icon-wrap">
<SolidIcon name="plus" fill="#3E63DD" className="add-new-workspace-icon" dataCy="add-new-workspace-link" />
</div>
<span className="p-1 tj-text-xsm">{t('header.organization.addNewWorkSpace', 'Add new workspace')}</span>
</div>
<div className={`${darkMode && 'dark-theme'}`}>{props.children}</div>
</div>
</components.Menu>
);
@ -65,22 +58,18 @@ const SingleValue = ({ selectProps }) => {
};
export const CustomSelect = ({ ...props }) => {
const [showEditOrg, setShowEditOrg] = useState(false);
const [showCreateOrg, setShowCreateOrg] = useState(false);
const darkMode = localStorage.getItem('darkMode') === 'true';
const currentValue = props?.options.find((option) => option?.value === props?.value);
return (
<>
<CreateOrganization showCreateOrg={showCreateOrg} setShowCreateOrg={setShowCreateOrg} />
<EditOrganization showEditOrg={showEditOrg} setShowEditOrg={setShowEditOrg} currentValue={currentValue} />
<Select
className={`react-select-container ${darkMode && 'dark-theme'}`}
width={'262px'}
hasSearch={false}
components={{ Menu, SingleValue }}
setShowEditOrg={setShowEditOrg}
setShowCreateOrg={setShowCreateOrg}
styles={{ border: 0, cursor: 'pointer' }}
{...props}

View file

@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { authenticationService } from '@/_services';
import { CustomSelect } from './CustomSelect';
import { getAvatar, decodeEntities } from '@/_helpers/utils';
@ -6,13 +6,15 @@ import { appendWorkspaceId, getWorkspaceIdOrSlugFromURL } from '@/_helpers/route
import { ToolTip } from '@/_components';
import { useCurrentSessionStore } from '@/_stores/currentSessionStore';
import { shallow } from 'zustand/shallow';
import SolidIcon from '@/_ui/Icon/SolidIcons';
import { EditOrganization } from './EditOrganization';
/* TODO:
each workspace related component has organizations list component which can be moved to a single wrapper.
otherwise this component will intiate everytime we switch between pages
*/
export const OrganizationList = function () {
const { current_organization_id } = authenticationService.currentSessionValue;
const { current_organization_id, admin } = authenticationService.currentSessionValue;
const { fetchOrganizations, organizationList, isGettingOrganizations } = useCurrentSessionStore(
(state) => ({
organizationList: state.organizations,
@ -32,34 +34,71 @@ export const OrganizationList = function () {
const organization = organizationList.find((org) => org.id === id);
if (![id, organization.slug].includes(getWorkspaceIdOrSlugFromURL())) {
const newPath = appendWorkspaceId(organization.slug || id, location.pathname, true);
window.history.replaceState(null, null, newPath);
window.location.reload();
window.open(newPath, '_blank');
}
};
const options = organizationList.map((org) => ({
value: org.id,
name: org.name,
slug: org.slug,
label: (
<div className={`align-items-center d-flex tj-org-dropdown ${darkMode && 'dark-theme'}`}>
<div
className="dashboard-org-avatar "
data-cy={`${String(org.name).toLowerCase().replace(/\s+/g, '-')}-avatar`}
>
{getAvatar(org.name)}
const options = organizationList
.map((org) => ({
value: org.id,
name: org.name,
slug: org.slug,
label: (
<div className={`align-items-center d-flex tj-org-dropdown ${darkMode && 'dark-theme'}`}>
{org.id === current_organization_id ? (
<div className="current-org-avatar">
<SolidIcon name="tick" fill="#3E63DD" dataCy="add-new-workspace-link" width="20" viewBox="0 0 17 15" />
</div>
) : (
<div
className="dashboard-org-avatar "
data-cy={`${String(org.name).toLowerCase().replace(/\s+/g, '-')}-avatar`}
>
{getAvatar(org.name)}
</div>
)}
<ToolTip message={org.name} placement="right">
<div className="org-name" data-cy={`${String(org.name).toLowerCase().replace(/\s+/g, '-')}-name-selector`}>
<span style={{ color: org.id === current_organization_id ? '#3E63DD' : 'var(--slate12)' }}>
{decodeEntities(org.name)}
</span>
</div>
</ToolTip>
{org.id === current_organization_id && admin ? (
<ToolTip message="Edit" placement="top">
<div
className="current-org-indicator"
data-cy="current-org-indicator"
onClick={() => setShowEditOrg(true)}
>
<SolidIcon name="editable" fill="#3E63DD" dataCy="add-new-workspace-link" width="16" />
</div>
</ToolTip>
) : (
org.id !== current_organization_id && (
<ToolTip message="Open in new tab" placement="top">
<div
className="current-org-indicator"
data-cy="current-org-indicator"
onClick={() => switchOrganization(org.id)}
>
<SolidIcon name="newtab" fill="var(--icon-strong)" width="16" className="add-new-workspace-icon" />
</div>
</ToolTip>
)
)}
</div>
<ToolTip message={org.name} placement="right">
<div className="org-name" data-cy={`${String(org.name).toLowerCase().replace(/\s+/g, '-')}-name-selector`}>
{decodeEntities(org.name)}
</div>
</ToolTip>
</div>
),
}));
),
}))
.sort((a, b) => (a.value === current_organization_id ? -1 : b.value === current_organization_id ? 1 : 0));
const [showEditOrg, setShowEditOrg] = useState(false);
const currentValue = organizationList.find((option) => option?.id === current_organization_id);
return (
<div className="org-select-container">
<EditOrganization showEditOrg={showEditOrg} setShowEditOrg={setShowEditOrg} currentValue={currentValue} />
<CustomSelect
isLoading={isGettingOrganizations}
options={options}

View file

@ -10670,6 +10670,33 @@ tbody {
border-radius: 6px;
}
.current-org-avatar {
margin-right: 11px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 7px 8px;
gap: 10px;
width: 34px;
height: 34px;
border-radius: 6px;
}
.current-org-indicator {
padding: 0px 8px 0px 8px;
margin-left: auto;
margin-right: 5px;
}
.current-org-indicator {
display: none;
}
&:hover .current-org-indicator {
display: block;
}
.org-name {
color: var(--slate12) !important;
white-space: nowrap;
@ -10678,6 +10705,10 @@ tbody {
}
}
.org-dropdown-shadow{
box-shadow: var(--elevation-400-box-shadow)
}
.css-1q0xftk-menu {
background-color: var(--base-black) !important;
border: 1px solid hsl(197, 6.8%, 13.6%) !important;
@ -10695,6 +10726,14 @@ tbody {
.org-custom-select-header-wrap {
border-bottom: 1px solid var(--slate5);
.select-header-font{
font-size: 14px;
font-weight: 500;
line-height: 20px;
color: var(--text-default);
}
}
.btn-close:focus {

View file

@ -0,0 +1,21 @@
import React from 'react';
const NewTab = ({ fill = '#6A727C', width = '25', className = '', viewBox = '0 0 25 25' }) => (
<svg
width={width}
height={width}
viewBox="0 0 17 17"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M13.8139 1.86633C14.6029 1.86633 15.2425 2.50593 15.2425 3.2949V10.914C15.2425 11.7029 14.6029 12.3425 13.8139 12.3425H6.19489C5.40591 12.3425 4.76632 11.7029 4.76632 10.914V3.2949C4.76632 2.50593 5.40591 1.86633 6.19489 1.86633H13.8139ZM11.4883 8.4777L10.5648 7.5542L8.60473 9.51427C8.32579 9.79321 7.87352 9.79321 7.59458 9.51427C7.31564 9.23532 7.31564 8.78306 7.59458 8.50411L9.55465 6.54405L8.63116 5.62056C8.46092 5.45032 8.41 5.1943 8.50212 4.97188C8.59426 4.74946 8.8113 4.60443 9.05206 4.60443H11.9092C12.2379 4.60443 12.5044 4.87092 12.5044 5.19967V8.05681C12.5044 8.29756 12.3594 8.51461 12.137 8.60674C11.9145 8.69887 11.6585 8.64794 11.4883 8.4777ZM3.33775 5.91395C3.33775 5.51947 3.01795 5.19967 2.62347 5.19967C2.22898 5.19967 1.90918 5.51947 1.90918 5.91395V13.0568C1.90918 14.2402 2.86857 15.1997 4.05204 15.1997H11.1949C11.5894 15.1997 11.9092 14.8799 11.9092 14.4854C11.9092 14.0909 11.5894 13.7711 11.1949 13.7711H4.05204C3.65755 13.7711 3.33775 13.4513 3.33775 13.0568V5.91395Z"
fill={fill}
/>
</svg>
);
export default NewTab;

View file

@ -123,6 +123,7 @@ import AddRectangle from './AddRectangle.jsx';
import Lock from './Lock.jsx';
import Mail from './Mail.jsx';
import Logs from './Logs.jsx';
import NewTab from './NewTab.jsx';
import Marketplace from './Marketplace.jsx';
import Minimize from './Minimize.jsx';
import Maximize from './Maximize.jsx';
@ -354,6 +355,8 @@ const Icon = (props) => {
return <NotificationSilent {...props} />;
case 'notificationunread':
return <NotificationUnread {...props} />;
case 'newtab':
return <NewTab {...props} />;
case 'options':
return <Options {...props} />;
case 'open':

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -8,19 +8,19 @@
</p>
<div class="social-links">
<a target="_blank" href="https://github.com/ToolJet/ToolJet/stargazers">
<img class="social-icons" alt="Company" src="cid:github" />
<img height="20" width="auto" class="social-icons" alt="Company" src="cid:github" />
</a>
<a target="_blank" href="https://www.linkedin.com/company/tooljet">
<img class="social-icons" alt="Company" src="cid:linkedin" />
<img height="20" width="auto" class="social-icons" alt="Company" src="cid:linkedin" />
</a>
<a
target="_blank"
href="https://www.youtube.com/channel/UCf1p2G5Z7fPpvlBPf4l2I1w"
>
<img class="social-icons" alt="Company" src="cid:youtube" />
<img height="20" width="auto" class="social-icons" alt="Company" src="cid:youtube" />
</a>
<a target="_blank" href="https://twitter.com/ToolJet">
<img class="social-icons" alt="Company" src="cid:twitter" />
<img height="20" width="auto" class="social-icons" alt="Company" src="cid:twitter" />
</a>
</div>
</div>

View file

@ -1,9 +1,9 @@
<div class="header">
<div class="logo-container padding-x-40 padding-y-20">
{{#if (eq whiteLabelText "ToolJet")}}
<img class="company-logo" alt="Company" src="cid:rocket" />
<img height="30" width="auto" class="company-logo" alt="Company" src="cid:rocket" />
{{else}}
<img class="white-label-logo" alt="Company" src={{whiteLabelLogo}} />
<img height="30" width="30" class="white-label-logo" alt="Company" src={{whiteLabelLogo}} />
{{/if}}
</div>
</div>