Pending Backlog Issues (#10823)

* folder-count-fix

* fixed query

* fixed app sharing bug

* minor css fix for delete group-button

* changed delete button color for light mode

* profile photo missing in groups

* ui fix for alignment

* css fix

* updated regex for email validation

* ui-fix for syncing the ui file with ee

* fix for workspace settings page

* workspace slug fix

* reverted some minor change

* minor ui fix

* folder-rerender changes
This commit is contained in:
Rohan Lahori 2024-10-21 12:37:09 +05:30 committed by GitHub
parent 3a8fa29f58
commit 0249102c08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 92 additions and 60 deletions

View file

@ -401,40 +401,43 @@ class ManageAppUsersComponent extends React.Component {
</div>
</div>
)}
{((this?.props?.isVersionReleased && this?.props?.isPublic) ||
window?.public_config?.ENABLE_PRIVATE_APP_EMBED === 'true') && (
<div className="tj-app-input">
<label className="field-name" data-cy="iframe-link-label">
Embedded app link
</label>
<span className={`tj-text-input justify-content-between ${this.props.darkMode ? 'dark' : ''}`}>
<span data-cy="iframe-link">{embeddableLink}</span>
<span className="copy-container">
<CopyToClipboard text={embeddableLink} onCopy={() => toast.success('Link copied to clipboard')}>
<svg
className="cursor-pointer"
width="17"
height="18"
viewBox="0 0 17 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
data-cy="iframe-link-copy-button"
{/* shows embedded app link only for released apps */}
{this?.props?.isVersionReleased &&
(this?.props?.isPublic || window?.public_config?.ENABLE_PRIVATE_APP_EMBED === 'true') && (
<div className="tj-app-input">
<label className="field-name" data-cy="iframe-link-label">
Embedded app link
</label>
<span className={`tj-text-input justify-content-between ${this.props.darkMode ? 'dark' : ''}`}>
<span data-cy="iframe-link">{embeddableLink}</span>
<span className="copy-container">
<CopyToClipboard
text={embeddableLink}
onCopy={() => toast.success('Link copied to clipboard')}
>
<path
d="M9.11154 5.18031H5.88668V4.83302C5.88668 3.29859 7.13059 2.05469 8.66502 2.05469H12.8325C14.3669 2.05469 15.6109 3.29859 15.6109 4.83302V9.00052C15.6109 10.535 14.3669 11.7789 12.8325 11.7789H12.4852V8.554C12.4852 6.69076 10.9748 5.18031 9.11154 5.18031Z"
fill="#889096"
/>
<path
d="M8.66502 15.9464H4.49752C2.96309 15.9464 1.71918 14.7025 1.71918 13.168V9.00052C1.71918 7.46609 2.96309 6.22219 4.49752 6.22219H8.66502C10.1994 6.22219 11.4434 7.46609 11.4434 9.00052V13.168C11.4434 14.7025 10.1994 15.9464 8.66502 15.9464Z"
fill="#889096"
/>
</svg>
</CopyToClipboard>
<svg
className="cursor-pointer"
width="17"
height="18"
viewBox="0 0 17 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
data-cy="iframe-link-copy-button"
>
<path
d="M9.11154 5.18031H5.88668V4.83302C5.88668 3.29859 7.13059 2.05469 8.66502 2.05469H12.8325C14.3669 2.05469 15.6109 3.29859 15.6109 4.83302V9.00052C15.6109 10.535 14.3669 11.7789 12.8325 11.7789H12.4852V8.554C12.4852 6.69076 10.9748 5.18031 9.11154 5.18031Z"
fill="#889096"
/>
<path
d="M8.66502 15.9464H4.49752C2.96309 15.9464 1.71918 14.7025 1.71918 13.168V9.00052C1.71918 7.46609 2.96309 6.22219 4.49752 6.22219H8.66502C10.1994 6.22219 11.4434 7.46609 11.4434 9.00052V13.168C11.4434 14.7025 10.1994 15.9464 8.66502 15.9464Z"
fill="#889096"
/>
</svg>
</CopyToClipboard>
</span>
</span>
</span>
</div>
)}
</div>
)}
</div>
}
</Modal.Body>

View file

@ -55,10 +55,10 @@ const AppList = (props) => {
className={`d-block text-center text-body ${props.darkMode && 'text-white-50'}`}
data-cy="empty-folder-text"
>
{/* removed this error message display for now -> as it was leading to multiple message being shown in the UI*/}
{/* {props.currentFolder?.count == 0
? t('homePage.thisFolderIsEmpty', 'This folder is empty')
: t('homePage.nonAccessibleFolderApps', 'You do not have access to any applications in this folder.')} */}
{props.currentFolder?.count == 0 &&
props.apps?.length == 0 &&
props.appSearchKey == '' &&
t('homePage.thisFolderIsEmpty', 'This folder is empty')}
</span>
</div>
)}

View file

@ -25,6 +25,7 @@ export const Folders = function Folders({
canDeleteFolder,
canCreateApp,
darkMode,
searchedAppCount,
}) {
const [isLoading, setLoadingStatus] = useState(foldersLoading);
const [showInput, setShowInput] = useState(false);
@ -40,11 +41,14 @@ export const Folders = function Folders({
const [activeFolder, setActiveFolder] = useState(currentFolder || {});
const [filteredData, setFilteredData] = useState(folders);
const [errorText, setErrorText] = useState('');
const [activeFolderAppCount, setActiveFolderAppCount] = useState(activeFolder.count);
const navigate = useNavigate();
const { t } = useTranslation();
const { updateSidebarNAV } = useContext(BreadCrumbContext);
useEffect(() => {
setActiveFolderAppCount(searchedAppCount);
}, [searchedAppCount]);
useEffect(() => {
setLoadingStatus(foldersLoading);
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -107,6 +111,7 @@ export const Folders = function Folders({
updateSidebarNAV(folder?.name ?? 'All apps');
//update the url query parameter with folder name
updateFolderQuery(folder?.name);
setActiveFolderAppCount(folder.count);
}
function updateFolderQuery(name) {
@ -311,7 +316,11 @@ export const Folders = function Folders({
className="flex-grow-1 tj-folder-list tj-text-xsm"
data-cy={`${folder.name.toLowerCase().replace(/\s+/g, '-')}-name`}
>
{`${folder.name}${folder.count > 0 ? ` (${folder.count})` : ''}`}
{folder.id === activeFolder.id ? (
<span>{`${folder.name}${folder.count > 0 ? ` (${activeFolderAppCount})` : ''}`}</span>
) : (
<span>{`${folder.name}${folder.count > 0 ? ` (${folder.count})` : ''}`}</span>
)}
</div>
</ToolTip>
{(canDeleteFolder || canUpdateFolder) && (

View file

@ -107,6 +107,7 @@ class HomePageComponent extends React.Component {
this.setState({
apps: data.apps,
meta: { ...this.state.meta, ...data.meta },
searchedAppCount: appSearchKey ? data.apps.length : this.state.currentFolder.count,
isLoading: false,
})
);
@ -842,6 +843,7 @@ class HomePageComponent extends React.Component {
canUpdateFolder={this.canUpdateFolder()}
darkMode={this.props.darkMode}
canCreateApp={this.canCreateApp()}
searchedAppCount={this.state.searchedAppCount}
/>
<OrganizationList />
</div>
@ -900,7 +902,7 @@ class HomePageComponent extends React.Component {
canCreateApp={this.canCreateApp}
/>
)}
{!isLoading && meta.total_count === 0 && appSearchKey && (
{!isLoading && apps?.length === 0 && appSearchKey && (
<div>
<span className={`d-block text-center text-body pt-5 ${this.props.darkMode && 'text-white-50'}`}>
{this.props.t('homePage.noApplicationFound', 'No Applications found')}
@ -921,6 +923,7 @@ class HomePageComponent extends React.Component {
darkMode={this.props.darkMode}
appActionModal={this.appActionModal}
removeAppFromFolder={this.removeAppFromFolder}
appSearchKey={this.state.appSearchKey}
/>
)}
</div>

View file

@ -20,6 +20,8 @@ import { SearchBox } from '@/_components/SearchBox';
import EditRoleErrorModal from '@/ManageGroupPermissionsV2/ErrorModal/ErrorModal';
import ChangeRoleModal from '@/ManageGroupPermissionResourcesV2/ChangeRoleModal';
import { ToolTip } from '@/_components/ToolTip';
import Avatar from '@/_ui/Avatar';
class ManageGroupPermissionResourcesComponent extends React.Component {
constructor(props) {
super(props);
@ -339,7 +341,6 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
this.setState({ isChangeRoleModalOpen: true, updatingUserRole: updatingUser });
showChangeRoleModalMessage = () => {
console.log('called');
this.setState({ showRoleEditMessage: true });
};
@ -435,7 +436,6 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
autoRoleChangeModalList,
autoRoleChangeMessageType,
} = this.state;
const isBasicPlan = false;
const isPaidPlan = false;
@ -737,11 +737,16 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
key={user.id}
className="manage-group-users-row"
data-cy={`${String(user.email).toLowerCase().replace(/\s+/g, '-')}-user-row`}
style={{ alignItems: 'center' }}
>
<p className="tj-text-sm d-flex align-items-center">
<div className="name-avatar">
{`${user?.firstName?.[0] ?? ''} ${user?.lastName?.[0] ?? ''}`}
</div>
<Avatar
className="name-avatar"
avatarId={user.avatarId}
text={`${user.first_name ? user.first_name[0] : ''}${
user.last_name ? user.last_name[0] : ''
}`}
/>
<span>{`${user?.firstName ?? ''} ${user?.lastName ?? ''}`}</span>
</p>
<p className="tj-text-sm d-flex align-items-center" style={{ paddingLeft: '12px' }}>

View file

@ -42,19 +42,20 @@ export function OrganizationSettings(props) {
if (selectedTabFromRoute === 'workspace-settings') {
// No Sub routes added loading first one
setSelectedTab(admin ? workspaceSettingsLinks[0].id : 'workspacevariables');
navigate(admin ? workspaceSettingsLinks[0].route : 'workspace-variables');
} else {
const selectedWorkspaceSetting = workspaceSettingsLinks?.find((m) => m.id === selectedTabFromRoute);
updateSidebarNAV(selectedWorkspaceSetting?.name || '');
setSelectedTab(getMenuFromRoute(selectedTabFromRoute)?.id);
}
return () => subscription.unsubscribe();
}, [authenticationService.currentSessionValue?.admin]);
useEffect(() => {
const menu = workspaceSettingsLinks?.find((m) => m.id === selectedTab);
updateSidebarNAV(menu?.name || '');
navigate(menu?.route || '');
}, [selectedTab]);
}, [admin, location.pathname]);
const handleClick = (data) => {
setSelectedTab(data.id);
updateSidebarNAV(data?.name || '');
};
return (
<Layout switchDarkMode={props.switchDarkMode} darkMode={props.darkMode}>
<div className="wrapper organization-settings-page">
@ -67,6 +68,7 @@ export function OrganizationSettings(props) {
<Wrapper key={index}>
<Link
key={index}
to={item.route}
style={{
textDecoration: 'none',
border: 'none',
@ -79,7 +81,7 @@ export function OrganizationSettings(props) {
className="workspace-settings-nav-items"
key={index}
onClick={() => {
setSelectedTab(item.id);
handleClick(item);
}}
selectedItem={selectedTab == item.id}
renderBadgeForItems={[]}

View file

@ -58,6 +58,7 @@ export const CreateOrganization = ({ showCreateOrg, setShowCreateOrg }) => {
};
const handleInputChange = async (value, field) => {
const trimmedValue = value?.trim();
if (field === 'slug') {
setSlug({
...slug,
@ -83,7 +84,7 @@ export const CreateOrganization = ({ showCreateOrg, setShowCreateOrg }) => {
if (error?.status === true) {
try {
await organizationService.checkWorkspaceUniqueness(
field === 'name' ? value : null,
field === 'name' ? trimmedValue : null,
field === 'slug' ? value : null
);
} catch (errResponse) {

View file

@ -578,7 +578,7 @@ export function validateDates({ validationObject, widgetValue, currentState, cus
export function validateEmail(email) {
const emailRegex =
/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[a-zA-Z]{2,})$/i;
return emailRegex.test(email);
}
@ -1099,9 +1099,9 @@ export const validateName = (
checkReservedWords = false,
allowAllCases = false
) => {
const newName = name.trim();
const newName = name;
let errorMsg = '';
if (emptyCheck && !newName) {
if (emptyCheck && (!newName || newName.trim().length === 0)) {
errorMsg = `${nameType} can't be empty`;
showError &&
toast.error(errorMsg, {

View file

@ -9841,7 +9841,7 @@ tbody {
.manage-group-users-row {
display: flex;
flex-direction: row;
align-items: baseline;
align-items: center;
padding: 12px 6px;
width: 612px !important;
height: 64px;
@ -10567,7 +10567,14 @@ tbody {
}
.disable {
color: var(--slate7);
color: var(--slate9);
}
.disable {
color: var(--slate9);
&.dark-theme {
color: var(--slate11);
}
}
&__danger {

View file

@ -1,3 +1,4 @@
.query-manager-border-color{
input.form-control,
textarea,
.input-control {
@ -51,7 +52,7 @@ textarea,
}
}
}
.empty-key-value {
border-radius: 6px;
padding: 10px;

View file

@ -234,6 +234,7 @@ export function getUserInGroupQuery(
'users.firstName',
'users.lastName',
'users.email',
'users.avatarId',
'userRole.id',
'role.name',
'organizationUsers.status',

View file

@ -107,7 +107,7 @@ export class FoldersService {
.innerJoin('folderApp.app', 'app', 'folderApp.folderId = :id', {
id: folder.id,
})
.where('app.name LIKE :name', { name: `%${searchKey}%` })
.where('LOWER(app.name) LIKE :name', { name: `%${(searchKey ?? '').toLowerCase()}%` })
.getMany();
const userPermission = await this.abilityService.resourceActionsPermission(user, {