diff --git a/package-lock.json b/package-lock.json
index 3ec8ba3..607364f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2664,9 +2664,9 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8700,9 +8700,9 @@
}
},
"node_modules/eslint/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12610,9 +12610,9 @@
"dev": true
},
"node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"license": "MIT",
"dependencies": {
diff --git a/src/components/IconLoader.jsx b/src/components/IconLoader.jsx
index caa6577..b068a2b 100644
--- a/src/components/IconLoader.jsx
+++ b/src/components/IconLoader.jsx
@@ -64,6 +64,10 @@ import ITOps from "./icons/itops";
import Tenant from "./icons/Tenant";
import Role from "./icons/Role";
import User from "./icons/User";
+import DirectoryIcon from "./icons/Directory";
+import Employee from "./icons/Employee";
+import Customer from "./icons/Customer";
+import HumanResources from "./icons/HumanResources";
const icon_components = {
@@ -79,22 +83,26 @@ const icon_components = {
config_group: ConfigManagementIcon,
config_management: ConfigManagementIcon,
copy: CopyIcon,
+ customer: Customer,
device_status_bad: InventoryStatusBadIcon,
device_status_ok: InventoryStatusOkIcon,
device_status_unk: InventoryStatusUknIcon,
device_status_warn: InventoryStatusWarnIcon,
devops: CodeIcon,
+ directory: DirectoryIcon,
documentation: Documentation,
reply: ReplyIcon,
delete: DeleteIcon,
device: DeviceIcon,
edit: EditIcon,
+ employee: Employee,
feature_flag: FeatureFlag,
git: Git,
github: GitHub,
gitlab: GitLab,
help: HelpIcon,
history: HistoryIcon,
+ human_resources: HumanResources,
information: InformationIcon,
kb: InformationIcon,
itam: ItamIcon,
diff --git a/src/components/InlineFields.jsx b/src/components/InlineFields.jsx
index c45eb21..065cc2f 100644
--- a/src/components/InlineFields.jsx
+++ b/src/components/InlineFields.jsx
@@ -360,10 +360,11 @@ export const InlineFieldAction = async ({ request, params }) => {
const update = await apiFetch(
document.location.pathname,
-
null,
request.method,
- form_data
+ form_data,
+ false,
+ false
)
.then(data => {
diff --git a/src/components/Table.jsx b/src/components/Table.jsx
index 7a28094..b242616 100644
--- a/src/components/Table.jsx
+++ b/src/components/Table.jsx
@@ -29,7 +29,7 @@ const Table = ({
const API_SPLIT = String('api/v2')
- const [loaded, setPageLoaded] = useState(false)
+ const [loaded, setPageLoaded] = useState(loader_data ? true : false)
const [metadata, setMetaData] = useState(null);
@@ -54,7 +54,6 @@ const Table = ({
useEffect(() => {
- setPageLoaded(false)
setMetaData(loader_metadata)
setTableData(loader_data)
setPageNumberValue(1)
@@ -84,7 +83,6 @@ const Table = ({
}
}
- setPageLoaded(true)
}, [
// loader_metadata,
@@ -94,8 +92,6 @@ const Table = ({
useEffect(() =>{
- setPageLoaded(false)
-
let url = null
if( page !== 0 ) {
@@ -108,59 +104,58 @@ const Table = ({
}
- apiFetch( url )
- .then((result) => {
+ if( loaded === false || page !== 0 ) {
+ apiFetch( url )
+ .then((result) => {
+ if( result.status == 200 ) {
- if( result.status == 200 ) {
+ if( result.api_metadata !== null ) {
- if( result.api_metadata !== null ) {
+ setMetaData(result.api_metadata)
+
+ }
+
+ setTableData(result.api_page_data)
- setMetaData(result.api_metadata)
-
- }
-
- setTableData(result.api_page_data)
+ if( Array(result.api_metadata.table_fields).length < 2 ) {
- if( Array(result.api_metadata.table_fields).length < 2 ) {
+ console.error("Missing Table Fields")
- console.error("Missing Table Fields")
+ }
- }
+ if( SetContentHeaderIcon ) {
- if( SetContentHeaderIcon ) {
+ SetContentHeaderIcon(
+ <>
+ {result.api_metadata['documentation'] &&
+
+
+
+ }
+ >
+ )
+ }
- SetContentHeaderIcon(
- <>
- {result.api_metadata['documentation'] &&
-
-
-
- }
- >
- )
- }
+ if( callback ) {
- if( callback ) {
+ callback(result.api_metadata.name)
- callback(result.api_metadata.name)
+ }
- }
+ if( page !== 0 ) {
+
+ setPageNumberValue(page)
- if( page !== 0 ) {
-
- setPageNumberValue(page)
+ }
+ setPageLoaded(true)
}
-
- setPageLoaded(true)
-
}
-
- })
-
+ )
+ }
}, [
page,
]);
@@ -199,9 +194,7 @@ const Table = ({
return (
<>
- { loaded &&
- <>
- { metadata &&
+ { loaded && (metadata && table_data) &&
{ metadata.allowed_methods.includes('POST') && (
)}
@@ -502,8 +495,6 @@ const Table = ({
}
>
- }
- >
);
}
diff --git a/src/components/form/Menu.jsx b/src/components/form/Menu.jsx
index 2661eb7..97e46f1 100644
--- a/src/components/form/Menu.jsx
+++ b/src/components/form/Menu.jsx
@@ -30,14 +30,13 @@ const Menu = ({
const dropDownMenuId = useId();
const dropDownMenuItemsId = useId();
- const dropDownMenu = document.getElementById(dropDownMenuId)
-
document.onclick = (e) => {
handleMenuClose(e)
}
const handleMenuClose = (e) => {
+ const dropDownMenu = document.getElementById(dropDownMenuId)
e.stopPropagation()
@@ -46,6 +45,7 @@ const Menu = ({
const handleMenuToggle = (e) => {
+ const dropDownMenu = document.getElementById(dropDownMenuId)
e.stopPropagation()
diff --git a/src/components/form/Textarea.jsx b/src/components/form/Textarea.jsx
index 70da349..a09367e 100644
--- a/src/components/form/Textarea.jsx
+++ b/src/components/form/Textarea.jsx
@@ -104,8 +104,9 @@ const TextArea = ({
}
}}
-
- >{value}
+
+ value={value}
+ >
>
)
diff --git a/src/components/icons/Customer.jsx b/src/components/icons/Customer.jsx
new file mode 100644
index 0000000..ee93520
--- /dev/null
+++ b/src/components/icons/Customer.jsx
@@ -0,0 +1,14 @@
+const Customer = ({
+ width = '20px',
+ height = '20px',
+ fill = '#FFF'
+}) => {
+
+ return (
+
+ );
+}
+
+export default Customer;
diff --git a/src/components/icons/Directory.jsx b/src/components/icons/Directory.jsx
new file mode 100644
index 0000000..576cd1a
--- /dev/null
+++ b/src/components/icons/Directory.jsx
@@ -0,0 +1,14 @@
+const DirectoryIcon = ({
+ width = '20px',
+ height = '20px',
+ fill = '#FFF'
+}) => {
+
+ return (
+
+ );
+}
+
+export default DirectoryIcon
\ No newline at end of file
diff --git a/src/components/icons/Employee.jsx b/src/components/icons/Employee.jsx
new file mode 100644
index 0000000..c42dcf9
--- /dev/null
+++ b/src/components/icons/Employee.jsx
@@ -0,0 +1,14 @@
+const Employee = ({
+ width = '20px',
+ height = '20px',
+ fill = '#FFF'
+}) => {
+
+ return (
+
+ );
+}
+
+export default Employee;
diff --git a/src/components/icons/HumanResources.jsx b/src/components/icons/HumanResources.jsx
new file mode 100644
index 0000000..a1339e0
--- /dev/null
+++ b/src/components/icons/HumanResources.jsx
@@ -0,0 +1,14 @@
+const HumanResources = ({
+ width = '20px',
+ height = '20px',
+ fill = '#FFF'
+}) => {
+
+ return (
+
+ );
+}
+
+export default HumanResources;
diff --git a/src/components/page/ticket/LinkedItems.jsx b/src/components/page/ticket/LinkedItems.jsx
index 47e5baf..3879640 100644
--- a/src/components/page/ticket/LinkedItems.jsx
+++ b/src/components/page/ticket/LinkedItems.jsx
@@ -5,6 +5,7 @@ import FieldData from "../../../functions/FieldData";
import { apiFetch } from "../../../hooks/apiFetch";
import Section from "../../Section";
+import IconLoader from "../../IconLoader";
@@ -14,6 +15,7 @@ const LinkedItems = ({
const [ page_data, setPageData ] = useState(null)
const [ metadata, setMetaData ] = useState(null)
+ const [ refresh, setRefresh ] = useState(false)
useEffect(() => {
@@ -29,9 +31,27 @@ const LinkedItems = ({
undefined,
undefined,
)
- }, [ data_url ])
+ }, [ data_url, refresh ])
+ const handleDeleteLinkedItem = (e) => {
+
+ let url = `${data_url}/${e.currentTarget.id}`
+
+ console.log(`Removing Linked Item ${url}`)
+
+ apiFetch(
+ url,
+ null,
+ 'DELETE',
+ null,
+ false
+ )
+
+ setRefresh( refresh ? false : true )
+
+ }
+
return (
@@ -75,6 +98,23 @@ const LinkedItems = ({
field_name='display_name'
data={linked_item}
/>
+
+
+
+
+
)
diff --git a/src/components/page/ticket/RelatedTickets.jsx b/src/components/page/ticket/RelatedTickets.jsx
index 5cc1813..6b6e162 100644
--- a/src/components/page/ticket/RelatedTickets.jsx
+++ b/src/components/page/ticket/RelatedTickets.jsx
@@ -16,6 +16,7 @@ const RelatedTickets = ({
const [ page_data, setPageData ] = useState(null)
const [ metadata, setMetaData ] = useState(null)
+ const [ refresh, setRefresh ] = useState(false)
useEffect(() => {
@@ -29,8 +30,23 @@ const RelatedTickets = ({
}
)
- },[ data_url ])
+ },[ data_url, refresh ])
+ const handleDeleteRelatedTicket = (e) => {
+
+ let url = `${data_url}/${e.currentTarget.id}`
+
+ console.log(`Removing Dependent ticket ${url}`)
+
+ apiFetch(
+ url,
+ null,
+ 'DELETE'
+ )
+
+ setRefresh( refresh ? false : true )
+
+ }
return (
{related_name}
+
+
-
+
+
+
diff --git a/src/components/page/ticket/TicketComment.jsx b/src/components/page/ticket/TicketComment.jsx
index 990b81f..ad282b6 100644
--- a/src/components/page/ticket/TicketComment.jsx
+++ b/src/components/page/ticket/TicketComment.jsx
@@ -8,17 +8,19 @@ import IconLoader from "../../IconLoader"
import { secondsToTime } from "../../../layout/Ticket"
import Section from "../../Section"
import TicketCommentForm from "./TicketCommentForm"
+import TicketComments from "./TicketComments"
const TicketComment = ({
- discussion = false,
comment_data = {},
metadata = null,
ticket_id = null,
post_url,
edit_callback = null,
- callback_value = null
+ callback_value = null,
+ parent_comment = null,
+ new_comment_url = null,
}) => {
if( String(post_url).includes('?') ) {
@@ -26,6 +28,12 @@ const TicketComment = ({
post_url = String(post_url).split('?')[0]
}
+ const [ comment_metadata, setCommentMetadata ] = useState( metadata )
+
+ const [ comment_page_data, setCommentPageData ] = useState( comment_data )
+
+ const [ start_thread, setStartThread ] = useState( false )
+
let comment_header = ' wrote'
let comment_class = 'comment comment-type-default'
@@ -36,19 +44,19 @@ const TicketComment = ({
try {
- if( isNaN(comment_data.comment_type) ) {
+ if( isNaN(comment_page_data.comment_type) ) {
- comment_type = comment_data.comment_type
+ comment_type = comment_page_data.comment_type
}else {
- comment_type = String(metadata.fields.comment_type.choices[Number(comment_data.comment_type)-1].display_name).toLowerCase()
+ comment_type = String(comment_metadata.fields.comment_type.choices[Number(comment_page_data.comment_type)-1].display_name).toLowerCase()
}
}catch( e ) {
- console.log('error: ' + comment_data.id )
+ console.error('error: ' + comment_page_data.id )
}
@@ -80,76 +88,87 @@ const TicketComment = ({
const comment_header_text_updated = (Updated )
const comment_header_text = (
- metadata && comment_data &&
+ comment_metadata && comment_page_data &&
{comment_header} on
{comment_updated && {comment_header_text_updated}
}
)
- const [threads_url, setThreadsURL] = useState(comment_data._urls.threads ? String(comment_data._urls.threads).split('api/v2')[1] : null)
-
- const [ threads, setThreads ] = useState(null)
- const [ reload, setRelaod ] = useState(false)
useEffect(() => {
- if( threads_url ) {
- apiFetch(
- threads_url + '?page[size]=500',
- (data) => {
- setThreads(data)
- },
- undefined,
- undefined,
- false
- )
-
- setRelaod(false)
- }
- },[ reload, threads_url ])
+ if( ! comment_metadata ) {
+
+ async function do_fetch() {
+
+ await apiFetch(
+ comment_page_data._urls._self,
+ null,
+ 'OPTIONS'
+ )
+ .then((result) => {
+
+ if( result.status === 200 ) {
+
+ if( result.api_metadata !== null ) {
+
+ setCommentMetadata(result.api_metadata)
+
+ }
+ }
+ })
+ }
+
+ do_fetch()
+
+ };
+
+ }, [])
+
if( comment_type === 'action' ) {
return(
-