@asaleh37/ui-base 25.12.16 → 25.12.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/__ODockerfile +14 -14
  2. package/dist/index.d.ts +0 -2
  3. package/dist/index.js +107 -107
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +112 -112
  6. package/dist/index.mjs.map +1 -1
  7. package/package-lock.json/342/200/216 +9039 -9039
  8. package/package.json +122 -122
  9. package/src/components/administration/admin/OrganizationMemberGrid.tsx +49 -63
  10. package/src/components/administration/admin/PersonGrid.tsx +344 -10
  11. package/src/components/templates/DataEntryTemplates/TemplateDataForm/FormElementField.tsx +238 -238
  12. package/src/components/templates/DataEntryTemplates/TemplateDataForm/TemplateForm.tsx +427 -427
  13. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/DataGridColumnsUtil.tsx +198 -198
  14. package/src/components/templates/DataEntryTemplates/TemplateDataGrid/TemplateGrid.tsx +1047 -1047
  15. package/src/components/templates/report/ExcelReportViewer.tsx +72 -72
  16. package/src/components/templates/report/ReportViewer.tsx +272 -272
  17. package/src/hooks/UseWindow.tsx +111 -111
  18. package/src/hooks/index.ts +22 -22
  19. package/src/hooks/useCommonStore.tsx +29 -29
  20. package/src/hooks/useParameterPanel.tsx +159 -159
  21. package/src/layout/NavigationTree.tsx +1 -8
  22. package/src/layout/TopBar.tsx +55 -72
  23. package/src/main.tsx +1 -2
  24. package/src/navigationItems/Administration/adminNavigationItems.tsx +1 -1
  25. package/src/redux/features/common/AppInfoSlice.ts +0 -4
  26. package/src/components/administration/admin/CustomPersonGrid.tsx +0 -361
  27. package/src/components/administration/admin/OrgProvidedPersonGrid.tsx +0 -347
@@ -1,111 +1,111 @@
1
- import { useEffect, useState } from "react";
2
- import {
3
- AppBar,
4
- Box,
5
- IconButton,
6
- Modal,
7
- Paper,
8
- Toolbar,
9
- Typography,
10
- } from "@mui/material";
11
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
12
- import { IconProp } from "@fortawesome/fontawesome-svg-core";
13
- import { useSelector } from "react-redux";
14
-
15
- export interface TemplateWindowProp {
16
- height?: any;
17
- width?: any;
18
- minWidth?: any;
19
- minHeight?: any;
20
- windowIcon?: IconProp;
21
- windowTitle?: string;
22
- onCloseCallBack?: any;
23
- }
24
-
25
- interface WindowProps {
26
- children?: React.ReactNode;
27
- }
28
-
29
- export const useWindow = (props: TemplateWindowProp) => {
30
- const [windowState, setWindowState] = useState(false);
31
- const appDirection = useSelector(
32
- (state: any) => state.AppLayout.appDirection
33
- );
34
- const Window: React.FC<WindowProps> = (windowProps: WindowProps) => {
35
- return (
36
- <Modal
37
- open={windowState}
38
- sx={{ zIndex: (theme) => theme.zIndex.drawer }}
39
- onClose={() => {
40
- if (!windowState && props?.onCloseCallBack) {
41
- props.onCloseCallBack();
42
- }
43
- }}
44
- >
45
- <Box
46
- dir={appDirection}
47
- sx={{
48
- position: "absolute",
49
- top: "50%",
50
- left: "50%",
51
- maxHeight: "90%",
52
- transform: "translate(-50%, -50%)",
53
- height: props?.height || "80%",
54
- width: props?.width || "90%",
55
- minWidth: props.minWidth || 400,
56
- minHeight: props.minHeight || 200,
57
- overflow: "hidden",
58
- bgcolor: "modalBackground.main",
59
- display: "flex",
60
- flexDirection: "column",
61
- alignItems: "center",
62
- justifyContent: "flex-start",
63
- }}
64
- >
65
- <AppBar position="static">
66
- <Toolbar variant="dense">
67
- <FontAwesomeIcon
68
- icon={props?.windowIcon || "window-maximize"}
69
- style={{ marginRight: 5 }}
70
- />
71
- <Typography variant="h6" color="inherit" component="div">
72
- {props?.windowTitle || "window"}
73
- </Typography>
74
- <div style={{ flexGrow: 1 }}></div>
75
- <IconButton
76
- onClick={() => {
77
- setWindowState(false);
78
- if (
79
- props.onCloseCallBack != undefined &&
80
- props.onCloseCallBack != null
81
- ) {
82
- props.onCloseCallBack();
83
- }
84
- }}
85
- color="secondary"
86
- >
87
- <FontAwesomeIcon icon="xmark-square" />
88
- </IconButton>
89
- </Toolbar>
90
- </AppBar>
91
- <Paper
92
- sx={{
93
- // flexGrow: 1,
94
- display: "flex",
95
- flexDirection: "column",
96
- alignItems: "center",
97
- width: "100%",
98
- height: "100%",
99
- padding: 1,
100
- // justifyContent: "center",
101
- overflow: "hidden",
102
- }}
103
- >
104
- {windowProps?.children}
105
- </Paper>
106
- </Box>
107
- </Modal>
108
- );
109
- };
110
- return { windowState, setWindowState, Window };
111
- };
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ AppBar,
4
+ Box,
5
+ IconButton,
6
+ Modal,
7
+ Paper,
8
+ Toolbar,
9
+ Typography,
10
+ } from "@mui/material";
11
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
12
+ import { IconProp } from "@fortawesome/fontawesome-svg-core";
13
+ import { useSelector } from "react-redux";
14
+
15
+ export interface TemplateWindowProp {
16
+ height?: any;
17
+ width?: any;
18
+ minWidth?: any;
19
+ minHeight?: any;
20
+ windowIcon?: IconProp;
21
+ windowTitle?: string;
22
+ onCloseCallBack?: any;
23
+ }
24
+
25
+ interface WindowProps {
26
+ children?: React.ReactNode;
27
+ }
28
+
29
+ export const useWindow = (props: TemplateWindowProp) => {
30
+ const [windowState, setWindowState] = useState(false);
31
+ const appDirection = useSelector(
32
+ (state: any) => state.AppLayout.appDirection
33
+ );
34
+ const Window: React.FC<WindowProps> = (windowProps: WindowProps) => {
35
+ return (
36
+ <Modal
37
+ open={windowState}
38
+ sx={{ zIndex: (theme) => theme.zIndex.drawer }}
39
+ onClose={() => {
40
+ if (!windowState && props?.onCloseCallBack) {
41
+ props.onCloseCallBack();
42
+ }
43
+ }}
44
+ >
45
+ <Box
46
+ dir={appDirection}
47
+ sx={{
48
+ position: "absolute",
49
+ top: "50%",
50
+ left: "50%",
51
+ maxHeight: "90%",
52
+ transform: "translate(-50%, -50%)",
53
+ height: props?.height || "80%",
54
+ width: props?.width || "90%",
55
+ minWidth: props.minWidth || 400,
56
+ minHeight: props.minHeight || 200,
57
+ overflow: "hidden",
58
+ bgcolor: "modalBackground.main",
59
+ display: "flex",
60
+ flexDirection: "column",
61
+ alignItems: "center",
62
+ justifyContent: "flex-start",
63
+ }}
64
+ >
65
+ <AppBar position="static">
66
+ <Toolbar variant="dense">
67
+ <FontAwesomeIcon
68
+ icon={props?.windowIcon || "window-maximize"}
69
+ style={{ marginRight: 5 }}
70
+ />
71
+ <Typography variant="h6" color="inherit" component="div">
72
+ {props?.windowTitle || "window"}
73
+ </Typography>
74
+ <div style={{ flexGrow: 1 }}></div>
75
+ <IconButton
76
+ onClick={() => {
77
+ setWindowState(false);
78
+ if (
79
+ props.onCloseCallBack != undefined &&
80
+ props.onCloseCallBack != null
81
+ ) {
82
+ props.onCloseCallBack();
83
+ }
84
+ }}
85
+ color="secondary"
86
+ >
87
+ <FontAwesomeIcon icon="xmark-square" />
88
+ </IconButton>
89
+ </Toolbar>
90
+ </AppBar>
91
+ <Paper
92
+ sx={{
93
+ // flexGrow: 1,
94
+ display: "flex",
95
+ flexDirection: "column",
96
+ alignItems: "center",
97
+ width: "100%",
98
+ height: "100%",
99
+ padding: 1,
100
+ // justifyContent: "center",
101
+ overflow: "hidden",
102
+ }}
103
+ >
104
+ {windowProps?.children}
105
+ </Paper>
106
+ </Box>
107
+ </Modal>
108
+ );
109
+ };
110
+ return { windowState, setWindowState, Window };
111
+ };
@@ -1,22 +1,22 @@
1
- import { useRef } from "react";
2
- import { useTranslation } from "react-i18next";
3
- import { useForm } from "react-hook-form";
4
- import { useParams } from "react-router-dom";
5
- import { zodResolver } from "@hookform/resolvers/zod";
6
- import { useNavigate } from "react-router-dom";
7
- import * as z from "zod";
8
- import { useDispatch, useSelector } from "react-redux";
9
- export { default as useAxios } from "./useAxios";
10
- export { useConfirmationWindow } from "./UseConfirmationWindow";
11
- export { default as useLoadingMask } from "./useLoadingMask";
12
- export { useIsMobile } from "./UseMobile";
13
- export { default as useSession } from "./UseSession";
14
- export { useWindow } from "./UseWindow";
15
- export { default as useApiActions } from "./useApiActions";
16
- export { default as useCommonStore } from "./useCommonStore";
17
- export { useDispatch };
18
- export { useSelector };
19
- export { useParams };
20
- export { useForm, zodResolver, z };
21
- export { useTranslation };
22
- export { useNavigate };
1
+ import { useRef } from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { useForm } from "react-hook-form";
4
+ import { useParams } from "react-router-dom";
5
+ import { zodResolver } from "@hookform/resolvers/zod";
6
+ import { useNavigate } from "react-router-dom";
7
+ import * as z from "zod";
8
+ import { useDispatch, useSelector } from "react-redux";
9
+ export { default as useAxios } from "./useAxios";
10
+ export { useConfirmationWindow } from "./UseConfirmationWindow";
11
+ export { default as useLoadingMask } from "./useLoadingMask";
12
+ export { useIsMobile } from "./UseMobile";
13
+ export { default as useSession } from "./UseSession";
14
+ export { useWindow } from "./UseWindow";
15
+ export { default as useApiActions } from "./useApiActions";
16
+ export { default as useCommonStore } from "./useCommonStore";
17
+ export { useDispatch };
18
+ export { useSelector };
19
+ export { useParams };
20
+ export { useForm, zodResolver, z };
21
+ export { useTranslation };
22
+ export { useNavigate };
@@ -1,29 +1,29 @@
1
- import { useDispatch, useSelector } from "react-redux";
2
- import { StoreMetaData } from "../types";
3
- import useAxios from "./useAxios";
4
- import { setStoreData } from "../redux/features/common/CommonStoreSlice";
5
-
6
- const useCommonStore = (storeKey: string) => {
7
- const dispatch = useDispatch();
8
- const { handleGetRequest } = useAxios();
9
- const store: StoreMetaData = useSelector(
10
- (state: any) => state?.commonStores?.stores[storeKey]
11
- );
12
- const reload = async () => {
13
- if (store && store?.url) {
14
- await handleGetRequest({
15
- endPointURI: store.url,
16
- showMask: true,
17
- successCallBkFn: (response: any) => {
18
- dispatch(setStoreData({ storeKey, data: response.data }));
19
- },
20
- failureCallBkFn: () => {
21
- dispatch(setStoreData({ storeKey, data: [] }));
22
- },
23
- });
24
- }
25
- };
26
- return { reload, data: store?.data, store };
27
- };
28
-
29
- export default useCommonStore;
1
+ import { useDispatch, useSelector } from "react-redux";
2
+ import { StoreMetaData } from "../types";
3
+ import useAxios from "./useAxios";
4
+ import { setStoreData } from "../redux/features/common/CommonStoreSlice";
5
+
6
+ const useCommonStore = (storeKey: string) => {
7
+ const dispatch = useDispatch();
8
+ const { handleGetRequest } = useAxios();
9
+ const store: StoreMetaData = useSelector(
10
+ (state: any) => state?.commonStores?.stores[storeKey]
11
+ );
12
+ const reload = async () => {
13
+ if (store && store?.url) {
14
+ await handleGetRequest({
15
+ endPointURI: store.url,
16
+ showMask: true,
17
+ successCallBkFn: (response: any) => {
18
+ dispatch(setStoreData({ storeKey, data: response.data }));
19
+ },
20
+ failureCallBkFn: () => {
21
+ dispatch(setStoreData({ storeKey, data: [] }));
22
+ },
23
+ });
24
+ }
25
+ };
26
+ return { reload, data: store?.data, store };
27
+ };
28
+
29
+ export default useCommonStore;
@@ -1,159 +1,159 @@
1
- import { useEffect, useState } from "react";
2
- import {
3
- Accordion,
4
- AccordionDetails,
5
- AccordionSummary,
6
- Box,
7
- FontAwesomeIcon,
8
- FormElementProps,
9
- TemplateForm,
10
- Typography,
11
- } from "../components";
12
- import { useTranslation } from "react-i18next";
13
-
14
- export type EntityParameter = {
15
- parameterCode: string;
16
- parameterLabel: string;
17
- parameterValueFormat?: string;
18
- parameterValueField?: string;
19
- parameterDisplayField?: string;
20
- parameterDataset?: Array<any>;
21
- parameterDataQueryId?: number;
22
- hidden?: boolean;
23
- mandatory?: boolean;
24
- defaultValue?: any;
25
- parameterType:
26
- | "text"
27
- | "number"
28
- | "date"
29
- | "datetime"
30
- | "combobox"
31
- | "checkbox"
32
- | "html"
33
- | "lookup";
34
- };
35
-
36
- export const getFormElementsFromParameters = (
37
- parameters: Array<EntityParameter>,
38
- parameterValues: any
39
- ) => {
40
- const formElements: Array<FormElementProps> = [];
41
- for (const parameter of parameters) {
42
- const formElement: FormElementProps = {
43
- type: "field",
44
- mode: "props",
45
- props: {
46
- fieldLabel: parameter?.parameterLabel,
47
- fieldName: parameter?.parameterCode,
48
- fieldType: parameter?.parameterType,
49
- hidden: parameter?.hidden,
50
- formProps: { fieldSize: { lg: 4, md: 6, sm: 12 } },
51
- required: parameter?.mandatory,
52
- defaultValue:
53
- parameterValues[parameter?.parameterCode] || parameter?.defaultValue,
54
- },
55
- };
56
- formElements.push(formElement);
57
- }
58
- return formElements;
59
- };
60
-
61
- interface UseParameterPanelProps {
62
- parameters: Array<EntityParameter>;
63
- initialParameterValues?: any;
64
- }
65
-
66
- export const useParameterPanel = (props: UseParameterPanelProps) => {
67
- const [parametersValues, setParametersValues] = useState<any>({
68
- ...props?.initialParameterValues,
69
- });
70
- const panelElements = getFormElementsFromParameters(
71
- props.parameters,
72
- parametersValues
73
- );
74
-
75
- const ParameterPanel: React.FC<{
76
- searchBtnClickCallBk: (params: any) => Promise<void>;
77
- }> = ({ searchBtnClickCallBk }) => {
78
- const { t } = useTranslation();
79
- return (
80
- <Accordion defaultExpanded sx={{ width: "100%" }}>
81
- <AccordionSummary
82
- expandIcon={
83
- <FontAwesomeIcon
84
- icon={{ prefix: "far", iconName: "square-caret-down" }}
85
- />
86
- }
87
- >
88
- <Box
89
- sx={{
90
- display: "flex",
91
- alignItems: "center",
92
- justifyContent: "center",
93
- }}
94
- >
95
- <FontAwesomeIcon
96
- style={{ marginLeft: 5, marginRight: 5 }}
97
- icon="search"
98
- />
99
- <Typography component="span">Filters</Typography>
100
- </Box>
101
- </AccordionSummary>
102
- <AccordionDetails>
103
- <Box>
104
- <TemplateForm
105
- saveButtonSpecs={{
106
- label: t("Filter"),
107
- icon: "search",
108
- actionButtonVariant: "outlined",
109
- actionButtonColor: "success",
110
- }}
111
- cancelButtonSpecs={{
112
- label: t("RESET_BTN_LABEL"),
113
- icon: "eraser",
114
- hidden: true,
115
- actionButtonVariant: "outlined",
116
- actionButtonColor: "error",
117
- }}
118
- actions={[
119
- {
120
- label: t("RESET_BTN_LABEL"),
121
- icon: "eraser",
122
- isIdRequired: false,
123
- formActionProps: { enabled: true },
124
- actionFn: async (data, recordIdsToProcessActionOn) => {
125
- setParametersValues({});
126
- },
127
- },
128
- ]}
129
- apiActions={{
130
- deleteRecordById: async () => {
131
- return true;
132
- },
133
- saveRecord: async (params) => {
134
- if (params != undefined) {
135
- setParametersValues(params);
136
- } else {
137
- setParametersValues({});
138
- }
139
- if (searchBtnClickCallBk) {
140
- await searchBtnClickCallBk(params);
141
- }
142
- },
143
- reloadData: async () => {},
144
- loadRecordById: async () => {},
145
- }}
146
- elements={panelElements}
147
- />
148
- </Box>
149
- </AccordionDetails>
150
- </Accordion>
151
- );
152
- };
153
- return {
154
- ParameterPanel,
155
- parametersValues,
156
- setParametersValues,
157
- panelElements,
158
- };
159
- };
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ Accordion,
4
+ AccordionDetails,
5
+ AccordionSummary,
6
+ Box,
7
+ FontAwesomeIcon,
8
+ FormElementProps,
9
+ TemplateForm,
10
+ Typography,
11
+ } from "../components";
12
+ import { useTranslation } from "react-i18next";
13
+
14
+ export type EntityParameter = {
15
+ parameterCode: string;
16
+ parameterLabel: string;
17
+ parameterValueFormat?: string;
18
+ parameterValueField?: string;
19
+ parameterDisplayField?: string;
20
+ parameterDataset?: Array<any>;
21
+ parameterDataQueryId?: number;
22
+ hidden?: boolean;
23
+ mandatory?: boolean;
24
+ defaultValue?: any;
25
+ parameterType:
26
+ | "text"
27
+ | "number"
28
+ | "date"
29
+ | "datetime"
30
+ | "combobox"
31
+ | "checkbox"
32
+ | "html"
33
+ | "lookup";
34
+ };
35
+
36
+ export const getFormElementsFromParameters = (
37
+ parameters: Array<EntityParameter>,
38
+ parameterValues: any
39
+ ) => {
40
+ const formElements: Array<FormElementProps> = [];
41
+ for (const parameter of parameters) {
42
+ const formElement: FormElementProps = {
43
+ type: "field",
44
+ mode: "props",
45
+ props: {
46
+ fieldLabel: parameter?.parameterLabel,
47
+ fieldName: parameter?.parameterCode,
48
+ fieldType: parameter?.parameterType,
49
+ hidden: parameter?.hidden,
50
+ formProps: { fieldSize: { lg: 4, md: 6, sm: 12 } },
51
+ required: parameter?.mandatory,
52
+ defaultValue:
53
+ parameterValues[parameter?.parameterCode] || parameter?.defaultValue,
54
+ },
55
+ };
56
+ formElements.push(formElement);
57
+ }
58
+ return formElements;
59
+ };
60
+
61
+ interface UseParameterPanelProps {
62
+ parameters: Array<EntityParameter>;
63
+ initialParameterValues?: any;
64
+ }
65
+
66
+ export const useParameterPanel = (props: UseParameterPanelProps) => {
67
+ const [parametersValues, setParametersValues] = useState<any>({
68
+ ...props?.initialParameterValues,
69
+ });
70
+ const panelElements = getFormElementsFromParameters(
71
+ props.parameters,
72
+ parametersValues
73
+ );
74
+
75
+ const ParameterPanel: React.FC<{
76
+ searchBtnClickCallBk: (params: any) => Promise<void>;
77
+ }> = ({ searchBtnClickCallBk }) => {
78
+ const { t } = useTranslation();
79
+ return (
80
+ <Accordion defaultExpanded sx={{ width: "100%" }}>
81
+ <AccordionSummary
82
+ expandIcon={
83
+ <FontAwesomeIcon
84
+ icon={{ prefix: "far", iconName: "square-caret-down" }}
85
+ />
86
+ }
87
+ >
88
+ <Box
89
+ sx={{
90
+ display: "flex",
91
+ alignItems: "center",
92
+ justifyContent: "center",
93
+ }}
94
+ >
95
+ <FontAwesomeIcon
96
+ style={{ marginLeft: 5, marginRight: 5 }}
97
+ icon="search"
98
+ />
99
+ <Typography component="span">Filters</Typography>
100
+ </Box>
101
+ </AccordionSummary>
102
+ <AccordionDetails>
103
+ <Box>
104
+ <TemplateForm
105
+ saveButtonSpecs={{
106
+ label: t("Filter"),
107
+ icon: "search",
108
+ actionButtonVariant: "outlined",
109
+ actionButtonColor: "success",
110
+ }}
111
+ cancelButtonSpecs={{
112
+ label: t("RESET_BTN_LABEL"),
113
+ icon: "eraser",
114
+ hidden: true,
115
+ actionButtonVariant: "outlined",
116
+ actionButtonColor: "error",
117
+ }}
118
+ actions={[
119
+ {
120
+ label: t("RESET_BTN_LABEL"),
121
+ icon: "eraser",
122
+ isIdRequired: false,
123
+ formActionProps: { enabled: true },
124
+ actionFn: async (data, recordIdsToProcessActionOn) => {
125
+ setParametersValues({});
126
+ },
127
+ },
128
+ ]}
129
+ apiActions={{
130
+ deleteRecordById: async () => {
131
+ return true;
132
+ },
133
+ saveRecord: async (params) => {
134
+ if (params != undefined) {
135
+ setParametersValues(params);
136
+ } else {
137
+ setParametersValues({});
138
+ }
139
+ if (searchBtnClickCallBk) {
140
+ await searchBtnClickCallBk(params);
141
+ }
142
+ },
143
+ reloadData: async () => {},
144
+ loadRecordById: async () => {},
145
+ }}
146
+ elements={panelElements}
147
+ />
148
+ </Box>
149
+ </AccordionDetails>
150
+ </Accordion>
151
+ );
152
+ };
153
+ return {
154
+ ParameterPanel,
155
+ parametersValues,
156
+ setParametersValues,
157
+ panelElements,
158
+ };
159
+ };
@@ -32,7 +32,6 @@ import useSession from "../hooks/UseSession";
32
32
  import { findNavigationItemById, NavigationItems } from "../navigationItems";
33
33
  import { DRAWER_WIDTH } from "../redux/features/common/AppLayoutSlice";
34
34
  import { toggleSideBarState } from "../redux/features/common/SideBarSlice";
35
- import { AppInfo } from "../redux/features/common/AppInfoSlice";
36
35
 
37
36
  function DotIcon() {
38
37
  return (
@@ -233,7 +232,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
233
232
  export default function NavigationTree() {
234
233
  const navigate = useNavigate();
235
234
  const appLayoutState = useSelector((state: any) => state.AppLayout);
236
- const AppInfo: AppInfo = useSelector((state: any) => state.AppInfo.value);
235
+ const AppInfo = useSelector((state: any) => state.AppInfo.value);
237
236
  const dispatch = useDispatch();
238
237
  const isMobile = useIsMobile();
239
238
  const toggleSideBar = () => {
@@ -244,12 +243,6 @@ export default function NavigationTree() {
244
243
  const filterData = (data) => {
245
244
  const parentItems = [];
246
245
  for (let parentItem of data) {
247
- if (
248
- parentItem.id === "development_admin.organization" &&
249
- !AppInfo.isUserProfileManaged
250
- ) {
251
- continue;
252
- }
253
246
  if (
254
247
  (parentItem.authority === undefined ||
255
248
  parentItem.authority == null ||