diff --git a/CHANGELOG.md b/CHANGELOG.md index 0184109ea..62ea12d31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,44 @@ Mark items as `Added`, `Changed`, `Fixed`, `Modified`, `Removed`, `Untested Features`, `Upcoming Features`, `Known Issues` +## 7.0.0 - 2025-01-10 + +`Added` + +**forms-flow-admin** +* Added permission selection option in role creation modal + +**forms-flow-theme** +* Added new root variables to support the updated UI design +* Added style changes to support new design + +**forms-flow-components** +* New micro-frontend to include reusable UI components +* Added new reusable components: + * Svg Icons + * Svg Images + * Custom components: + * Modals + * Button + * Form elements + * Table elements +

+ + +`Modified` + +**forms-flow-admin** +* Renamed Admin menu as Manage and moved to sidebar + +**forms-flow-nav** +* Modified Navbar to sidebar with updated design + + + + + + + ## 6.0.2 - 2024-06-05 `Generic Changes` diff --git a/README.md b/README.md index 790a22777..b5ab8c825 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ This module contains all the common functionalties used by micro front-ends. The This module contains the common style sheet shared by all micro-front-ends. This module supports theming by providing the option to use desired themes by modifying the css variables. +5. forms-flow-components + +This module contains reusable UI components. + All the modules are built with `single-spa`, a javascript router for micro front-end microsevices. ## Prerequisites diff --git a/VERSION b/VERSION index 5c6f460f0..7dbc37ae3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v7.0.0-alpha +v7.1.0-alpha diff --git a/forms-flow-admin/package-lock.json b/forms-flow-admin/package-lock.json index d22e1eeae..606db8357 100644 --- a/forms-flow-admin/package-lock.json +++ b/forms-flow-admin/package-lock.json @@ -1,12 +1,12 @@ { "name": "@formsflow/admin", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@formsflow/admin", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "dependencies": { "@types/react": "^17.0.19", "@types/react-dom": "^17.0.9", diff --git a/forms-flow-admin/package.json b/forms-flow-admin/package.json index 1b29a83fa..1c982ca51 100644 --- a/forms-flow-admin/package.json +++ b/forms-flow-admin/package.json @@ -1,6 +1,6 @@ { "name": "@formsflow/admin", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "scripts": { "start": "webpack serve", "start:standalone": "webpack serve --env standalone", diff --git a/forms-flow-admin/src/components/roles/roles.tsx b/forms-flow-admin/src/components/roles/roles.tsx index f3a5f55a4..f3c129c91 100644 --- a/forms-flow-admin/src/components/roles/roles.tsx +++ b/forms-flow-admin/src/components/roles/roles.tsx @@ -79,7 +79,6 @@ const Roles = React.memo((props: any) => { setDisabled( !( payload.name?.trim() && - payload.description?.trim() && payload.permissions.length !== 0 ) ); @@ -89,7 +88,6 @@ const Roles = React.memo((props: any) => { setDisabled( !( editCandidate.name?.trim() && - editCandidate.description?.trim() && editCandidate.permissions.length !== 0 ) ); @@ -181,7 +179,6 @@ const Roles = React.memo((props: any) => { const validateRolePayload = (payload) => { return !( payload.name === "" || - payload.description === "" || payload.permissions.length === 0 ); }; @@ -272,6 +269,7 @@ const Roles = React.memo((props: any) => { rowData.name, null, null, + null, (results) => { setUsers(results.data); setLoading(false); @@ -424,7 +422,6 @@ const Roles = React.memo((props: any) => { {t("Description")} - * { {t("Description")} - * { const [filter, setFilter] = React.useState(undefined); const [total, setTotal] = React.useState(undefined); const { t } = useTranslation(); - + const [sizePerPage, setSizePerPage] = React.useState(5); + React.useEffect(() => { if (filter === undefined) return; setLoading(true); @@ -29,6 +30,7 @@ const UserManagement = React.memo((props: any) => { filter, 1, search, + sizePerPage, (results) => { setUsers(removeTenantIdFromUserRoles(results.data)); setInvalidated(false); @@ -54,6 +56,7 @@ const UserManagement = React.memo((props: any) => { filter, 1, search, + sizePerPage, (results) => { setUsers(removeTenantIdFromUserRoles(results.data)); setInvalidated(false); @@ -80,6 +83,7 @@ const UserManagement = React.memo((props: any) => { filter, pageNo, search, + sizePerPage, (results) => { setUsers(removeTenantIdFromUserRoles(results.data)); setTotal(results.count); @@ -103,6 +107,7 @@ const UserManagement = React.memo((props: any) => { null, pageNo, null, + sizePerPage, (results) => { setUsers(removeTenantIdFromUserRoles(results.data)); @@ -122,7 +127,7 @@ const UserManagement = React.memo((props: any) => { setError(err); toast.error(t("Failed to fetch roles!")) }); - }, []); + }, [sizePerPage]); const removeTenantIdFromUserRoles = (data)=>{ let updatedUserData = [] @@ -151,6 +156,7 @@ const UserManagement = React.memo((props: any) => { setFilter={setFilter} total={total} error={error} + limit = {{sizePerPage , setSizePerPage}} /> ); diff --git a/forms-flow-admin/src/components/users/users.tsx b/forms-flow-admin/src/components/users/users.tsx index 9613f129d..9f1d2dbd7 100644 --- a/forms-flow-admin/src/components/users/users.tsx +++ b/forms-flow-admin/src/components/users/users.tsx @@ -26,7 +26,6 @@ const Users = React.memo((props: any) => { const [error, setError] = React.useState(null); // Initialize error state with null instead of undefined const [loading, setLoading] = React.useState(false); const [activePage, setActivePage] = React.useState(1); - const [sizePerPage, setSizePerPage] = React.useState(5); const [selectedFilter, setSelectedFilter] = React.useState(null); // Initialize selectedFilter with null const [searchKey, setSearchKey] = React.useState(""); const [showInviteModal, setShowInviteModal] = React.useState(false); // Add state for managing invite modal @@ -113,7 +112,8 @@ const Users = React.memo((props: any) => { }; const handleLimitChange = (newLimit: number) => { - setSizePerPage(newLimit); + props.limit?.setSizePerPage(newLimit); + props.page.setPageNo(1); setActivePage(1); }; @@ -524,7 +524,7 @@ const Users = React.memo((props: any) => { { } }, []); + React.useEffect(()=>{ + if(instance){ + publish("FF_AUTH", instance); + } + },[instance]) + React.useEffect(()=>{ if(!isAuth) return const locale = localStorage.getItem("i18nextLng") diff --git a/forms-flow-admin/src/services/users/index.ts b/forms-flow-admin/src/services/users/index.ts index 9435b7eaa..ac98f5bb5 100644 --- a/forms-flow-admin/src/services/users/index.ts +++ b/forms-flow-admin/src/services/users/index.ts @@ -6,6 +6,7 @@ export const fetchUsers = ( group: string | null, pageNo: number | null, search: string | null, + sizePerPage : number | null , callback: any, errorHandler: any, role = true, @@ -13,7 +14,8 @@ export const fetchUsers = ( ) => { let url = `${API.GET_USERS}?role=${role}&count=${count}`; if (group) url += `&memberOfGroup=${group}`; - if (pageNo) url += `&pageNo=${pageNo}&limit=5`; + if (pageNo) url += `&pageNo=${pageNo}`; + if(sizePerPage) url += `&limit=${sizePerPage}`; if (search) url += `&search=${search}`; RequestService.httpGETRequest(url) diff --git a/forms-flow-components/package-lock.json b/forms-flow-components/package-lock.json index 693e8c623..0f18ad252 100644 --- a/forms-flow-components/package-lock.json +++ b/forms-flow-components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@formsflow/components", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@formsflow/components", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "dependencies": { "@types/react": "^17.0.19", "@types/react-dom": "^17.0.9", diff --git a/forms-flow-components/package.json b/forms-flow-components/package.json index e68f60816..a64701fa4 100644 --- a/forms-flow-components/package.json +++ b/forms-flow-components/package.json @@ -1,6 +1,6 @@ { "name": "@formsflow/components", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "scripts": { "start": "webpack serve", "start:standalone": "webpack serve --env standalone", diff --git a/forms-flow-components/src/components/CustomComponents/CustomInfo.tsx b/forms-flow-components/src/components/CustomComponents/CustomInfo.tsx index 80e1d4c63..7e6702aba 100644 --- a/forms-flow-components/src/components/CustomComponents/CustomInfo.tsx +++ b/forms-flow-components/src/components/CustomComponents/CustomInfo.tsx @@ -1,4 +1,4 @@ -import React ,{ FC } from "react"; +import React, { FC } from "react"; import { useTranslation } from "react-i18next"; import { InfoIcon } from "../SvgIcons/index"; @@ -14,16 +14,24 @@ export const CustomInfo: FC = ( { content , className , }) => { - const { t } = useTranslation(); - return ( -
-
- -
{t(heading)}
-
-
- {t(content)} -
+ const { t } = useTranslation(); + + // Replace `\n` with
tags and use the line itself as a key + const formattedContent = content.split("\n").map((line) => ( + + {t(line)} +
+
+ )); + + + return ( +
+
+ +
{t(heading)}
- ) +
{formattedContent}
{/* Render formatted content */} +
+ ); }; \ No newline at end of file diff --git a/forms-flow-components/src/components/CustomComponents/FormBuilderModal.tsx b/forms-flow-components/src/components/CustomComponents/FormBuilderModal.tsx index 93ea8cf5c..549e1e877 100644 --- a/forms-flow-components/src/components/CustomComponents/FormBuilderModal.tsx +++ b/forms-flow-components/src/components/CustomComponents/FormBuilderModal.tsx @@ -151,6 +151,7 @@ export const FormBuilderModal: React.FC = React.memo( isInvalid={!!nameError} feedback={nameError} turnOnLoader={isFormNameValidating} + maxLength={200} /> void; onClick?: () => void; turnOnLoader?: boolean; - autoFocusInput?:boolean; + autoFocusInput?: boolean; + minLength?: number; + maxLength?: number; } export const FormInput: React.FC = ({ @@ -48,7 +50,9 @@ export const FormInput: React.FC = ({ onClick, turnOnLoader = false, autoFocusInput = false, -},) => { + minLength, + maxLength, +}) => { const { t } = useTranslation(); const inputClassNames = `form-control-input ${icon ? 'with-icon' : ''} ${className}`; const inputRef = useRef(null); @@ -65,32 +69,34 @@ export const FormInput: React.FC = ({ }; return ( - - {label && ( - - {t(label)} {required && *} - - )} - - - {turnOnLoader && ( + + {label && ( + + {t(label)}{required && *} + + )} + + + {turnOnLoader && (
)} {icon && !turnOnLoader &&( diff --git a/forms-flow-components/src/components/CustomComponents/FormTextArea.tsx b/forms-flow-components/src/components/CustomComponents/FormTextArea.tsx index 9632f1cfa..1f7f7e638 100644 --- a/forms-flow-components/src/components/CustomComponents/FormTextArea.tsx +++ b/forms-flow-components/src/components/CustomComponents/FormTextArea.tsx @@ -24,6 +24,8 @@ interface FormTextAreaProps { onIconClick?: () => void; maxRows?: number; iconPosition?: string; + minLength?: number; + maxLength?: number; } export const FormTextArea = forwardRef(({ @@ -46,7 +48,9 @@ export const FormTextArea = forwardRef(( minRows = 1, onIconClick, maxRows = 5, - iconPosition = "top" + iconPosition = "top", + minLength, + maxLength, }, ref) => { const { t } = useTranslation(); const internalRef = useRef(null); @@ -99,6 +103,8 @@ export const FormTextArea = forwardRef(( className={`custom-textarea form-control-input ${icon ? 'with-icon' : ''} ${className}`} style={{ maxHeight: `${maxRows * 1.5}em` }} onKeyDown={handleKeyDown} + minLength={minLength} + maxLength={maxLength} /> {icon && ( = ({ onBlurDropDown }) => { const { t } = useTranslation(); + const primaryColor = StyleServices.getCSSVariable('primary'); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [inputValue, setInputValue] = useState(selectedOption || ''); const [filteredItems, setFilteredItems] = useState([]); @@ -126,7 +127,7 @@ export const InputDropdown: React.FC = ({ ariaLabel={ariaLabelforInput} dataTestid={dataTestIdforInput} isInvalid={isInvalid} - icon={} + icon={} className="input-with-close" label={t(dropdownLabel)} feedback={t(feedback)} diff --git a/forms-flow-components/src/declarations.d.ts b/forms-flow-components/src/declarations.d.ts index bbb64dbe1..fdb490941 100644 --- a/forms-flow-components/src/declarations.d.ts +++ b/forms-flow-components/src/declarations.d.ts @@ -39,5 +39,5 @@ declare module "*.svg" { } declare module "@formsflow/service" { - export const { HelperServices }: any; + export const { HelperServices, StyleServices }: any; } \ No newline at end of file diff --git a/forms-flow-integration/package.json b/forms-flow-integration/package.json index 7d492c76b..631dc5a14 100644 --- a/forms-flow-integration/package.json +++ b/forms-flow-integration/package.json @@ -1,6 +1,6 @@ { "name": "@formsflow/integration", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "scripts": { "start": "webpack serve", "start:standalone": "webpack serve --env standalone", diff --git a/forms-flow-nav/package.json b/forms-flow-nav/package.json index 4e6f737f2..903bd7dfe 100644 --- a/forms-flow-nav/package.json +++ b/forms-flow-nav/package.json @@ -1,6 +1,6 @@ { "name": "@formsflow/nav", - "version": "7.0.0-alpha", + "version": "7.1.0-alpha", "scripts": { "start": "webpack serve", "start:standalone": "webpack serve --env standalone", diff --git a/forms-flow-nav/src/sidenav/Sidebar.jsx b/forms-flow-nav/src/sidenav/Sidebar.jsx index 59f36a0f6..0e2544c81 100644 --- a/forms-flow-nav/src/sidenav/Sidebar.jsx +++ b/forms-flow-nav/src/sidenav/Sidebar.jsx @@ -210,7 +210,7 @@ const Sidebar = React.memo(({ props, sidenavHeight="100%" }) => { const manageOptions = () => { const options = []; - if (isViewDashboard || isDashboardManager) { + if (isDashboardManager) { options.push({ name: "Dashboards", path: DASHBOARD_ROUTE, @@ -402,8 +402,8 @@ const Sidebar = React.memo(({ props, sidenavHeight="100%" }) => { }); Sidebar.propTypes = { - subscribe: PropTypes.func.isRequired, - getKcInstance: PropTypes.func.isRequired, + subscribe: PropTypes.func, + getKcInstance: PropTypes.func, publish: PropTypes.func, sidenavHeight: PropTypes.string, }; diff --git a/forms-flow-theme/scss/_modal.scss b/forms-flow-theme/scss/_modal.scss index 8398e26df..1a025fbdd 100644 --- a/forms-flow-theme/scss/_modal.scss +++ b/forms-flow-theme/scss/_modal.scss @@ -168,6 +168,17 @@ $secondary: var(--ff-secondary); flex-direction: column; gap: var(--spacer-150); } + + .long-form-name { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1.2em; + max-height: 2.4em; + word-wrap: break-word; + } } @@ -663,12 +674,13 @@ $secondary: var(--ff-secondary); .expression-area { display: flex; - height: 80px; + min-height: 80px; align-items: flex-start; gap: var(--spacer-050); border-radius: var(--radius-0100); border: 1px solid $primary; margin-top: 0.5rem; + padding-bottom: 0.5rem; flex-wrap: wrap; } @@ -908,3 +920,11 @@ $secondary: var(--ff-secondary); margin-top: 1.5rem; } } + + + + + + + + diff --git a/forms-flow-theme/scss/_theme.scss b/forms-flow-theme/scss/_theme.scss index bf11eb7bc..90643fdb3 100644 --- a/forms-flow-theme/scss/_theme.scss +++ b/forms-flow-theme/scss/_theme.scss @@ -54,6 +54,9 @@ $dropdown-link-hover-color: $dark; $btn-color: $dark; $popover-body-color: $dark; $btn-disabled-border-color: $gray-100; +$no-code-success: #1B9C85; +$no-code-secondary: #EA9389; +$no-code-warning: #faad14; $theme-colors: ( "primary": $primary, @@ -136,6 +139,10 @@ $theme-colors: map-merge($theme-colors, $custom-colors); --default-font-size: 1rem; --default-font-color: #{$gray-800}; --navbar-width: 192px; + //no-code colors + --no-code-success: #{$no-code-success}; + --no-code-secondary: #{$no-code-secondary}; + --no-code-warning: #{$no-code-warning}; //font-style --primary-font: "Roboto", sans-serif; //font-size diff --git a/forms-flow-theme/scss/_variables.scss b/forms-flow-theme/scss/_variables.scss index 3f56cb1bc..9a94777d8 100644 --- a/forms-flow-theme/scss/_variables.scss +++ b/forms-flow-theme/scss/_variables.scss @@ -235,8 +235,9 @@ hr { overflow-y: auto; } .scrollable-overview { - max-height: 80vh; + max-height: 90vh; overflow-y: auto; + padding-bottom: 5rem; } @mixin generate-overflow($axis, $value) { diff --git a/forms-flow-theme/scss/external/formio.scss b/forms-flow-theme/scss/external/formio.scss index 7a749385a..2875dc6c9 100644 --- a/forms-flow-theme/scss/external/formio.scss +++ b/forms-flow-theme/scss/external/formio.scss @@ -80,6 +80,12 @@ $secondary: var(--ff-secondary); ); .task-variable-modal { + .form-control:disabled { + pointer-events: none; + } + label { + cursor: pointer; + } .formio-form { .formio-component { // Apply hover effect only if the component is not in the ignored list @@ -98,6 +104,17 @@ $secondary: var(--ff-secondary); padding: 0; cursor: none; } + &.taskvariable-hiddent-component { + label { + text-align: center; + border: dashed 1px !important; + padding: 5px; + cursor: pointer; + } + input { + display: none; + } + } } } }