Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: v0.2.0 #30

Merged
merged 31 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
30108ab
feat: Support Markdown field
jon-nfc Nov 11, 2024
4159b2d
feat(layout): On form field error, scroll to top of form
jon-nfc Nov 11, 2024
50bccf6
feat(layout): Form field error, set to be no larger than field
jon-nfc Nov 11, 2024
57784ca
fix(layout): Ensure that Markdown code blocks do wrap text
jon-nfc Nov 11, 2024
2684ad7
feat(component): Add support for multi-select form field
jon-nfc Nov 11, 2024
619ceda
refactor(component): Pass in the entire field meta and have the compo…
jon-nfc Nov 11, 2024
5bd3fca
fix(component): dont attempt to access field in double column if it d…
jon-nfc Nov 11, 2024
9e89439
feat(layout): Cater for multi-select values
jon-nfc Nov 11, 2024
aefcfd1
feat(layout): display non-field errors at the top of the form
jon-nfc Nov 11, 2024
0bf19be
feat(function): Add Delete mehod to urlBuilder
jon-nfc Nov 11, 2024
d106e79
feat(component): Support Timezoned DateTime fields
jon-nfc Nov 11, 2024
966645b
feat(component): Correctly convert ISO8601 with TZ to display in brow…
jon-nfc Nov 13, 2024
a8b86c6
feat(component): Auto-Expand Text area to content height
jon-nfc Nov 13, 2024
6a49468
refactor(component): Pass field object directly to textarea
jon-nfc Nov 13, 2024
8aadb62
feat(component): Auto-Expand Text area to content height style
jon-nfc Nov 13, 2024
8e9d5ca
feat(component): Format a charfield as hyperlink is metadata has `aut…
jon-nfc Nov 13, 2024
aead474
fix(layout): within form handle JSON data correctly when an object
jon-nfc Nov 13, 2024
39cde5d
fix(layout): if field is dict, ensure initial data is correctly set t…
jon-nfc Nov 13, 2024
a3ca377
fix(hook): dont allow fields to be set to `undefined` within urlBuilder
jon-nfc Nov 13, 2024
8bd7e6f
feat(layout): Use the url's as provided by API for models
jon-nfc Nov 13, 2024
0c97232
feat: Add route for common model that contains PK
jon-nfc Nov 13, 2024
9200914
Merge pull request #27 from nofusscomputing/functioning-forms
jon-nfc Nov 13, 2024
11baa26
fix: correct logic for history route to work
jon-nfc Nov 14, 2024
77dc49d
chore: Remove reply to icons no longer used
jon-nfc Nov 14, 2024
2968b62
feat(component): Check for table data, if none report so
jon-nfc Nov 15, 2024
5729206
feat: add add route for ticket
jon-nfc Nov 15, 2024
54fdcff
fix: Add missing route for project task add
jon-nfc Nov 15, 2024
cc58aa9
feat(component): Add ticket comment inline editing
jon-nfc Nov 15, 2024
cf4db04
fix(layout): ensure all metadata is loaded prior to rendering a ticket
jon-nfc Nov 15, 2024
210e8c4
feat(component): Add missing navbar icons
jon-nfc Nov 15, 2024
0e3ce00
Merge pull request #28 from nofusscomputing/form-work
jon-nfc Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"recommendations": [
"orta.vscode-jest",
"eg2.vscode-npm-script",
"burkeholland.simple-react-snippets"
]
}
31 changes: 29 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,12 @@ function App() {
>
<Route path='/login' element={<Login/>}/>

<Route path="/core/:model/:pk/:action"
<Route path="/core/:model/:pk/history"
element={<History
setContentHeading={setContentHeading}
SetContentHeaderIcon={SetContentHeaderIcon}
/>}
errorElement={<ErrorPage /> }
loader = {detailsLoader}
/>

<Route path="/settings"
Expand All @@ -78,6 +77,16 @@ function App() {
loader = {detailsLoader}
/>

{/* project_management/project/2/project_task/41 */}
<Route path="/:module/:common_model/:common_pk/project_task/add"
element={<ModelForm
setContentHeading={setContentHeading}
SetContentHeaderIcon={SetContentHeaderIcon}
/>}
errorElement={<ErrorPage /> }
loader = {detailsLoader}
/>

{/* project_management/project/2/project_task/41 */}
<Route path="/:module/:common_model/:common_pk/project_task/:pk"
element={<Ticket
Expand All @@ -88,6 +97,15 @@ function App() {
loader = {detailsLoader}
/>

<Route path="/:module/ticket/:model/add"
element={<ModelForm
setContentHeading={setContentHeading}
SetContentHeaderIcon={SetContentHeaderIcon}
/>}
errorElement={<ErrorPage /> }
loader = {detailsLoader}
/>

<Route path="/:module/ticket/:model/:pk"
element={<Ticket
setContentHeading={setContentHeading}
Expand Down Expand Up @@ -159,6 +177,15 @@ function App() {
loader = {detailsLoader}
/>

<Route path="/:module/:common_model/:common_pk/:model/:pk"
element={<Detail
setContentHeading={setContentHeading}
SetContentHeaderIcon={SetContentHeaderIcon}
/>}
errorElement={<ErrorPage /> }
loader = {detailsLoader}
/>

</Route>
));

Expand Down
20 changes: 19 additions & 1 deletion src/components/IconLoader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import ItamIcon from "./icons/ItamIcon";
import MenuIcon from "./icons/MenuIcon";
import NavDownIcon from "./icons/NavDownIcon";
import NavRightIcon from "./icons/NavRightIcon";
import OrganizationIcon from "./icons/OrganizationIcon";
import SoftwareIcon from "./icons/SoftwareIcon";
import ReplyIcon from "./icons/ReplyIcon";
import NotificationIcon from "./icons/ticket/NotificationIcon";
Expand Down Expand Up @@ -36,13 +35,27 @@ import RelatedTicketBlocked from "./icons/ticket/RelatedTicketBlocked";
import HelpIcon from "./icons/HelpIcon";
import DeleteIcon from "./icons/DeleteIcon";
import HistoryIcon from "./icons/HistoryIcon";
import AccessIcon from "./icons/AccessIcon";
import AnsibleIcon from "./icons/AnsibleIcon";
import ClusterIcon from "./icons/ClusterIcon";
import ConfigManagementIcon from "./icons/ConfigManagementIcon";
import InformationIcon from "./icons/InformationIcon";
import ITIMIcon from "./icons/ITIMIcon";
import ServiceIcon from "./icons/ServiceIcon";
import SettingsIcon from "./icons/SettingsIcon";
import ProjectIcon from "./icons/ProjectIcon";
import OrganizationIcon from "./icons/OrganizationIcon";


const icon_components = {
access: AccessIcon,
action_add:ActionAddIcon,
action_install: ActionInstallIcon,
action_remove: ActionRemoveIcon,
ansible: AnsibleIcon,
assistance: AssistanceIcon,
cluster: ClusterIcon,
config_management: ConfigManagementIcon,
device_status_bad: InventoryStatusBadIcon,
device_status_ok: InventoryStatusOkIcon,
device_status_unk: InventoryStatusUknIcon,
Expand All @@ -53,15 +66,20 @@ const icon_components = {
edit: EditIcon,
help: HelpIcon,
history: HistoryIcon,
information: InformationIcon,
itam: ItamIcon,
itim: ITIMIcon,
link: LinkIcon,
menu: MenuIcon,
navdown: NavDownIcon,
navdoubleleft: NavDoubleLeftIcon,
navright: NavRightIcon,
notification: NotificationIcon,
organization: OrganizationIcon,
project: ProjectIcon,
service: ServiceIcon,
software: SoftwareIcon,
settings: SettingsIcon,
task: TaskIcon,
ticket_related_blocks: RelatedTicketBlocks,
ticket_related_blocked_by: RelatedTicketBlocked,
Expand Down
20 changes: 18 additions & 2 deletions src/components/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import FieldData from "../functions/FieldData";
import TextField from "./form/Textfield";
import { Link, useParams } from "react-router-dom";
import IconLoader from "./IconLoader";
import urlBuilder from "../hooks/urlBuilder";


/**
Expand Down Expand Up @@ -40,14 +41,18 @@ const Table = ({

const params = useParams();

const url_builder = urlBuilder(
params
)

if( ! String(data_url_path).startsWith('/') ) {
data_url_path = '/' + data_url_path
}


if( String(window.location.pathname).includes('/ticket/') ) {

data_url_path = '/' + params.module + '/ticket/' + params.model
data_url_path = '/' + url_builder.params.module + '/ticket/' + url_builder.params.model

}

Expand Down Expand Up @@ -230,12 +235,23 @@ const Table = ({

} else {

let autolink = false

if(
key == 'name'
|| key == 'title'
|| Boolean(metadata.fields[key].autolink)
) {
autolink = true
}

return (
<td>
<FieldData
metadata={metadata}
field_name={key}
data={data}
autolink = {autolink}
/>
</td>
)
Expand All @@ -250,7 +266,7 @@ const Table = ({
<td
onClick={(e) => {
let a = e
document.getElementById('expandable-' + e.currentTarget.parentElement.id).classList.toggle("hide-expandable-row")
document.getElementById('expandable-' + data.id).classList.toggle("hide-expandable-row")
}}
>
<IconLoader
Expand Down
16 changes: 7 additions & 9 deletions src/components/form/Select.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@

const Select = ({
id,
choices = [],
label,
helptext=null,
required=false,
error_text=null,
value = '',
onChange = null
onChange = null,
field_data = null
}) => {


Expand All @@ -21,15 +18,16 @@ const Select = ({

return (
<fieldset>
<label className="name" for={id}>{label}</label>
<label className="name" for={id}>{field_data.label}</label>
<select
id={id}
required={required}
required={field_data.required}
className="common-field"
onChange={onChange}
multiple = {field_data.relationship_type == 'ManyToMany' ? true : false}
>
<option value="">Please select an option</option>
{choices.map((choice) => {
{field_data.choices.map((choice) => {

let selected = false

Expand All @@ -52,7 +50,7 @@ const Select = ({

})}
</select>
<span className="help-text">{helptext}</span>
<span className="help-text">{field_data.help_text}</span>
<span className="error-text">{error_text}</span>
</fieldset>
);
Expand Down
64 changes: 59 additions & 5 deletions src/components/form/Textarea.jsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,81 @@
const TextArea = ({
id,
label,
helptext=null,
required=false,
error_text=null,
value= '',
onChange = null,
class_name = null
class_name = null,
field_data = null
}) => {

if( value === null ) {
value = ''
}

let field_class_name = "common-field"
let helptext = null
let required = false
let label = ''

if( field_data ) {

field_data = Object(field_data)



if( 'help_text' in field_data) {

helptext = field_data['help_text']

}

if( 'label' in field_data ) {

label = field_data['label']

}

if( 'required' in field_data) {

required = field_data['required']

}

if( 'style' in field_data ) {

if( 'class' in field_data.style ) {

field_class_name += String( ' ' + field_data['style']['class'])

}
}
}


return (
<fieldset className={class_name}>
<label className="name" for={id}>{label}</label>
<span className="help-text">{helptext}</span>
<textarea
id={id}
required={required}
className="common-field"
className={field_class_name}
onChange={onChange}
onKeyUp={(e) =>{

const currentScrollY = window.scrollY

e.target.style.height = "1px";
e.target.style.height = ( 25 + e.target.scrollHeight ) + "px";

window.scrollTo(0, currentScrollY); // Prevent window scrolling to y=0

}}
onClick={(e) =>{

e.target.style.height = "1px";
e.target.style.height = ( 25 + e.target.scrollHeight ) + "px";

}}

>{value}</textarea>
<span className="error-text">{error_text}</span>
Expand Down
8 changes: 7 additions & 1 deletion src/components/form/Textfield.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ const TextField = ({
)
if( type === 'datetime-local') {

if( String(value).includes('+') ) {

value = String(value).split('+')[0]

}

field = (
<input
className="common-field"
Expand All @@ -40,7 +46,7 @@ const TextField = ({
// placeholder={helptext}
required={required}
type={type}
// value={value}
value={value}
/>
)

Expand Down
14 changes: 14 additions & 0 deletions src/components/icons/AccessIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const AccessIcon = ({
width = '20px',
height = '20px',
fill = '#FFF'
}) => {

return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" width={ width } height={ height } fill={ fill }>
<path d="M96-144v-648h384v144h384v504H96Zm72-72h240v-72H168v72Zm0-144h240v-72H168v72Zm0-144h240v-72H168v72Zm0-144h240v-72H168v72Zm312 432h312v-360H480v360Zm72-216v-72h168v72H552Zm0 144v-72h168v72H552Z"/>
</svg>
);
}

export default AccessIcon
14 changes: 14 additions & 0 deletions src/components/icons/AnsibleIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const AnsibleIcon = ({
width = '20px',
height = '20px',
fill = '#FFF'
}) => {

return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width={ width } height={ height } fill={ fill }>
<path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2M16.1 17C15.91 17 15.76 16.9 15.55 16.73L10.39 12.56L8.66 16.9H7.17L11.54 6.39C11.65 6.11 11.89 5.97 12.17 5.97C12.45 5.97 12.67 6.11 12.79 6.39L16.77 15.97C16.81 16.08 16.84 16.19 16.84 16.26C16.83 16.68 16.5 17 16.1 17M12.17 8.11L14.76 14.5L10.85 11.42L12.17 8.11Z" />
</svg>
);
}

export default AnsibleIcon
14 changes: 14 additions & 0 deletions src/components/icons/ClusterIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const ClusterIcon = ({
width = '20px',
height = '20px',
fill = '#FFF'
}) => {

return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width={ width } height={ height } fill={ fill }>
<path d="M4,1C2.89,1 2,1.89 2,3V7C2,8.11 2.89,9 4,9H1V11H13V9H10C11.11,9 12,8.11 12,7V3C12,1.89 11.11,1 10,1H4M4,3H10V7H4V3M3,12V14H5V12H3M14,13C12.89,13 12,13.89 12,15V19C12,20.11 12.89,21 14,21H11V23H23V21H20C21.11,21 22,20.11 22,19V15C22,13.89 21.11,13 20,13H14M3,15V17H5V15H3M14,15H20V19H14V15M3,18V20H5V18H3M6,18V20H8V18H6M9,18V20H11V18H9Z" />
</svg>
);
}

export default ClusterIcon
Loading
Loading