mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-02-09 08:19:41 +00:00
Compare commits
1 Commits
79c90ac92c
...
imgbot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5dc879733 |
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM python:3.6
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD . /app
|
||||
|
||||
RUN pip install -r requirements.txt && \
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
|
||||
5
Pipfile
5
Pipfile
@@ -49,7 +49,7 @@ PyPOM = "~=2.2.0"
|
||||
python-dateutil = "~=2.8.1"
|
||||
pytoml = "~=0.1.21"
|
||||
pytz = "~=2020.5"
|
||||
reportlab = "*"
|
||||
reportlab = "~=3.5.59"
|
||||
requests = "~=2.25.1"
|
||||
retrying = "~=1.3.3"
|
||||
simplejson = "~=3.17.2"
|
||||
@@ -63,6 +63,7 @@ tornado = "~=6.1"
|
||||
urllib3 = "~=1.26.5"
|
||||
whitenoise = "~=5.2.0"
|
||||
yolk = "~=0.4.3"
|
||||
"z3c.rml" = "~=4.1.2"
|
||||
zipp = "~=3.4.0"
|
||||
"zope.component" = "~=4.6.2"
|
||||
"zope.deferredimport" = "~=4.3.1"
|
||||
@@ -78,8 +79,6 @@ python-barcode = "*"
|
||||
django-hCaptcha = "*"
|
||||
importlib-metadata = "*"
|
||||
django-hcaptcha = "*"
|
||||
"z3c.rml" = "*"
|
||||
pikepdf = "*"
|
||||
|
||||
[dev-packages]
|
||||
selenium = "~=3.141.0"
|
||||
|
||||
115
Pipfile.lock
generated
115
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "841781f4c4d3c12a34c0ff8ef3fd58171baf657478d5c339d4f6fc79d5830978"
|
||||
"sha256": "7db5b3a9029be79c79efff791a42803a4765fe52c4f264f8a7be48ac4b1bda7a"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -73,7 +73,6 @@
|
||||
},
|
||||
"brotli": {
|
||||
"hashes": [
|
||||
"sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d",
|
||||
"sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8",
|
||||
"sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b",
|
||||
"sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c",
|
||||
@@ -83,13 +82,10 @@
|
||||
"sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181",
|
||||
"sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130",
|
||||
"sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19",
|
||||
"sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa",
|
||||
"sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429",
|
||||
"sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126",
|
||||
"sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4",
|
||||
"sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0",
|
||||
"sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b",
|
||||
"sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6",
|
||||
"sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438",
|
||||
"sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f",
|
||||
"sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389",
|
||||
@@ -101,13 +97,10 @@
|
||||
"sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430",
|
||||
"sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296",
|
||||
"sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12",
|
||||
"sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f",
|
||||
"sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d",
|
||||
"sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a",
|
||||
"sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452",
|
||||
"sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c",
|
||||
"sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761",
|
||||
"sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649",
|
||||
"sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b",
|
||||
"sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea",
|
||||
"sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c",
|
||||
@@ -117,23 +110,15 @@
|
||||
"sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5",
|
||||
"sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7",
|
||||
"sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d",
|
||||
"sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c",
|
||||
"sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43",
|
||||
"sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa",
|
||||
"sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17",
|
||||
"sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb",
|
||||
"sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb",
|
||||
"sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b",
|
||||
"sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4",
|
||||
"sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3",
|
||||
"sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7",
|
||||
"sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1",
|
||||
"sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb",
|
||||
"sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91",
|
||||
"sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b",
|
||||
"sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1",
|
||||
"sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806",
|
||||
"sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3",
|
||||
"sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"
|
||||
],
|
||||
"index": "pypi",
|
||||
@@ -401,10 +386,10 @@
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06",
|
||||
"sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"
|
||||
"sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6",
|
||||
"sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"
|
||||
],
|
||||
"version": "==0.13.0"
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"html5lib": {
|
||||
"hashes": [
|
||||
@@ -431,12 +416,12 @@
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6",
|
||||
"sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"
|
||||
"sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6",
|
||||
"sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==4.10.1"
|
||||
"version": "==4.10.0"
|
||||
},
|
||||
"lxml": {
|
||||
"hashes": [
|
||||
@@ -604,7 +589,6 @@
|
||||
"sha256:cd575cf0131683a7b661357bfd777b27c3c6c0d0fb7ef27e627f521122f75536",
|
||||
"sha256:fb3d7fb390192cfb1e287503dbc03229c1c77fe9820cf084546bb63fa997fd87"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.3.1"
|
||||
},
|
||||
"pillow": {
|
||||
@@ -801,53 +785,38 @@
|
||||
},
|
||||
"reportlab": {
|
||||
"hashes": [
|
||||
"sha256:0430cfe397415759839ef89abee6db82e8a8f9bb5831a3c93e7763915c755345",
|
||||
"sha256:13072e33e8cbac6fd6e776fecabdefafb0261886b2ab7cb3b874a9384f1b0ffe",
|
||||
"sha256:1767106d03320e76a708d2c40488fe1785580a0d7abac7715e01a3cc910c1179",
|
||||
"sha256:17f35a856bbf46989d557d4016822bcdd3ada88d3afb567de03a4b29676aa52e",
|
||||
"sha256:19414f4357287a7573a60bcb76a092c9ea82bf09f01d04b3afb5c1bd3c660df2",
|
||||
"sha256:1d8d9674eb6ba1b6c3d6a8e3d5d4e4231b3576db653d1b1fdac2538afee54c7a",
|
||||
"sha256:23236dc70598b688e979444c4840c5cec88a2a12fe81ba6f8cc807120a2cad33",
|
||||
"sha256:28c339d25eab804a8bd004dfaa5a80c7568178561741f4ce6e69dae05d38041f",
|
||||
"sha256:2c93a551b60c7fd3b17942772847f7c4ee2f08ae74c87ef8f325fe8083d2aa6e",
|
||||
"sha256:2e80045f36dd4b9b63b19fc073149f70857fe8590027ab3658db80ac6235ecd0",
|
||||
"sha256:38aa912301d93e2267861d820cb3f6eebed8deb58d0df429421578b9ba033eee",
|
||||
"sha256:47587ce01cf9ac25f6d187116a9f9cef710dc58ccea001024d950c4f5a504643",
|
||||
"sha256:587b3d8ce0a065a00975516013aebb062e6161fba3cf399b22f270e4d9a3db1e",
|
||||
"sha256:5a650284cc09caa32b5845c055bf035cb76949b87d57e9eed56d98f863613417",
|
||||
"sha256:5e113c630b6109efe0285230706c8423bff1b82c2e2824e441401a467a1215b7",
|
||||
"sha256:68e339411cc9329ff50982a7c1d55eabd53ac9be24d4442088af58328bae54d3",
|
||||
"sha256:6ae1fb03faf4b6710e2c081d5208416a5d557e0cc00ff24fc124dd42a7158114",
|
||||
"sha256:6f363e09aacaa7aaff232197fddb667d899822aa57d10091aea4fbb1f56b7fa7",
|
||||
"sha256:70841d7eb4aa2f8ad4afacce07711481a0dcd9d01679da5627173443131a33a2",
|
||||
"sha256:71d91002878c4d2a17a6bd7208c59373e6148977fe674bb79eec3eb9e63aa20f",
|
||||
"sha256:7a09e5bf9c8e02c373e5e558cc5c2cfbc5d3c68560a406c6d16254363cfa989e",
|
||||
"sha256:85095ef9f3697859064cb1b22f19659bf4ba25e7dadb9c6be65f322cd68ba88f",
|
||||
"sha256:8dafdcdde7243f0864d6d11dd9bfffbd1e6bce6c3e668fe992f56ae48377c822",
|
||||
"sha256:9a822486a98fe002bbe248fdf3f126739c1ad29032b54b71a3f67b6364a77677",
|
||||
"sha256:aa57dc0818e066fdced9457b9e6c6fb269d63e2d96902001c7dbe010bce6ebcc",
|
||||
"sha256:b0836c6cdee4b88e2366e0ff152c1327578149e09850b7cab6016444c5b3eb26",
|
||||
"sha256:b2988ffc33032096e808e7a4a36f5b453fcc9587873c85c1b44bc6846bbbd09c",
|
||||
"sha256:bd38d58895b359ef429df3c97dc00c3fef0ab57f45556de416ba9b7d7fc71ae2",
|
||||
"sha256:be87dca9253efd3cd0f351b785530c02e67664e284e3c4a97cdd0c7dd806d39a",
|
||||
"sha256:c21bdb11d7fccea28bf08eac13d9d031836e335c5e0620eae1d4336f193e9a03",
|
||||
"sha256:c43f847f2598b5c2fc9b63871d7da641c0b90e384d8da8018d4d7173a0b82cd4",
|
||||
"sha256:c780cc5208c67b25bdddd08480f874614cd0ec0bed39e1a848448543f2093945",
|
||||
"sha256:c9bcf696bc8935ff90ecb50c7644e2af01f63a444d4b4bd39d41d2abdd7bb224",
|
||||
"sha256:cb48b71088f5c9eff5715dde0bd4d5372d4713ffa92247acf0f04fd17ab2078d",
|
||||
"sha256:d48f638893b3eb4c9b2afeec2de4f95a4b57fb8c398e3d7f9a7fb4b4d9546820",
|
||||
"sha256:d8fe27ad312671c9347cf5997f7c1017833fac17233f33296281ba9fa0de189a",
|
||||
"sha256:d98b759661070f5588b30152d0caaf16ac387f60372f8fa2568c9ad4014cd7f3",
|
||||
"sha256:e2022ad36409e7616ed6311f7ab113f236cac66ba0d22be4f53bf7e77654b143",
|
||||
"sha256:e45159f4d19304f5e79be13283fe53bdd006c4fd4d93ff3cb6ac082ca017c418",
|
||||
"sha256:eb3ef5394b4b2c904ab467dbbe1efcfbe046e1395c2d3064420ccef89806570e",
|
||||
"sha256:f326b04a3fb3c7c58b799bd23b60790b181893f052fe5a8011c9cd9984e24a43",
|
||||
"sha256:f401ed014ea861dea2ae621f7810fb15b3bc021e6487dee97b32f175bbf1b7eb",
|
||||
"sha256:f4d4eb3a949ccb0782e4d6560fcd5ee6f34636d1ee24f1d2a2b1f530af89481a",
|
||||
"sha256:fdc3dc1242be557f6a8bb9e21751296cc721f60b8e2b684690049e656d798520"
|
||||
"sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd",
|
||||
"sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca",
|
||||
"sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e",
|
||||
"sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360",
|
||||
"sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72",
|
||||
"sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9",
|
||||
"sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f",
|
||||
"sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07",
|
||||
"sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba",
|
||||
"sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd",
|
||||
"sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34",
|
||||
"sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1",
|
||||
"sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab",
|
||||
"sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f",
|
||||
"sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd",
|
||||
"sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44",
|
||||
"sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490",
|
||||
"sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203",
|
||||
"sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4",
|
||||
"sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a",
|
||||
"sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd",
|
||||
"sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb",
|
||||
"sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7",
|
||||
"sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea",
|
||||
"sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b",
|
||||
"sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f",
|
||||
"sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd",
|
||||
"sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b",
|
||||
"sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.6.5"
|
||||
"version": "==3.5.68"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
@@ -872,11 +841,11 @@
|
||||
},
|
||||
"sentry-sdk": {
|
||||
"hashes": [
|
||||
"sha256:141da032f0fa4c56f9af6b361fda57360af1789576285bd1944561f9c274f9c0",
|
||||
"sha256:9aeff2a47f4038460296b920bf4d269284e8454e1c67547ee002ccafd9c2442b"
|
||||
"sha256:2cec50166bcb67e1965f8073541b2321e3864cd6fd42a526bcde9f0c4e4cc3f8",
|
||||
"sha256:7bbaa32bba806ec629962f207b597e86831c7ee2c1f287c21ba7de7fea9a9c46"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.5.3"
|
||||
"version": "==1.5.2"
|
||||
},
|
||||
"simplejson": {
|
||||
"hashes": [
|
||||
@@ -1113,10 +1082,10 @@
|
||||
},
|
||||
"z3c.rml": {
|
||||
"hashes": [
|
||||
"sha256:11eca2ffe2e5db6d53b5a19617126db780afe779e11b5215651c8214aa98d8a6"
|
||||
"sha256:0d730e2e61a29c69822ee955366f9d7e9a82e6909c11932329629fb0c1a128a0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.2.0"
|
||||
"version": "==4.1.2"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
|
||||
@@ -120,10 +120,10 @@ class TextBox(Region):
|
||||
class SimpleMDETextArea(Region):
|
||||
@property
|
||||
def value(self):
|
||||
return self.driver.execute_script("return document.querySelector('#' + arguments[0]).nextSibling.children[1].CodeMirror.getDoc().getValue();", self.root.get_attribute("id"))
|
||||
return self.driver.execute_script("return document.querySelector('#' + arguments[0]).nextSibling.nextSibling.CodeMirror.getDoc().getValue();", self.root.get_attribute("id"))
|
||||
|
||||
def set_value(self, value):
|
||||
self.driver.execute_script("document.querySelector('#' + arguments[0]).nextSibling.children[1].CodeMirror.getDoc().setValue(arguments[1]);", self.root.get_attribute("id"), value)
|
||||
self.driver.execute_script("document.querySelector('#' + arguments[0]).nextSibling.nextSibling.CodeMirror.getDoc().setValue(arguments[1]);", self.root.get_attribute("id"), value)
|
||||
|
||||
|
||||
class CheckBox(Region):
|
||||
@@ -145,7 +145,7 @@ class RadioSelect(Region): # Currently only works for yes/no radio selects
|
||||
value = "0"
|
||||
else:
|
||||
value = "1"
|
||||
self.find_element(By.XPATH, f"//label[@for='{self.root.get_attribute('id')}_{value}']").click()
|
||||
self.find_element(By.XPATH, "//label[@for='{}_{}']".format(self.root.get_attribute("id"), value)).click()
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
|
||||
@@ -2,12 +2,13 @@ import datetime
|
||||
import operator
|
||||
from functools import reduce
|
||||
|
||||
import simplejson
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import messages
|
||||
from django.core import serializers
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse_lazy, reverse, NoReverseMatch
|
||||
from django.views import generic
|
||||
@@ -26,7 +27,7 @@ class Index(generic.TemplateView): # Displays the current rig count along with
|
||||
template_name = 'index.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context = super(Index, self).get_context_data(**kwargs)
|
||||
context['rig_count'] = models.Event.objects.rig_count()
|
||||
return context
|
||||
|
||||
@@ -38,7 +39,6 @@ class SecureAPIRequest(generic.View):
|
||||
'organisation': models.Organisation,
|
||||
'profile': models.Profile,
|
||||
'event': models.Event,
|
||||
'asset': asset_models.Asset,
|
||||
'supplier': asset_models.Supplier,
|
||||
'training_item': training_models.TrainingItem,
|
||||
}
|
||||
@@ -49,9 +49,8 @@ class SecureAPIRequest(generic.View):
|
||||
'organisation': 'RIGS.view_organisation',
|
||||
'profile': 'RIGS.view_profile',
|
||||
'event': None,
|
||||
'asset': None,
|
||||
'supplier': None,
|
||||
'training_item': None,
|
||||
'training_item': None, # TODO
|
||||
}
|
||||
|
||||
'''
|
||||
@@ -126,7 +125,8 @@ class SecureAPIRequest(generic.View):
|
||||
results.append(data)
|
||||
|
||||
# return a data response
|
||||
return JsonResponse(results, safe=False)
|
||||
json = simplejson.dumps(results)
|
||||
return HttpResponse(json, content_type="application/json") # Always json
|
||||
|
||||
start = request.GET.get('start', None)
|
||||
end = request.GET.get('end', None)
|
||||
@@ -151,7 +151,8 @@ class SecureAPIRequest(generic.View):
|
||||
}
|
||||
|
||||
results.append(data)
|
||||
return JsonResponse(results, safe=False)
|
||||
json = simplejson.dumps(results)
|
||||
return HttpResponse(json, content_type="application/json") # Always json
|
||||
|
||||
return HttpResponse(model)
|
||||
|
||||
@@ -175,7 +176,7 @@ class GenericListView(generic.ListView):
|
||||
paginate_by = 20
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context = super(GenericListView, self).get_context_data(**kwargs)
|
||||
context['page_title'] = self.model.__name__ + "s"
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
@@ -207,8 +208,8 @@ class GenericDetailView(generic.DetailView):
|
||||
template_name = "generic_detail.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['page_title'] = f"{self.model.__name__} | {self.object.name}"
|
||||
context = super(GenericDetailView, self).get_context_data(**kwargs)
|
||||
context['page_title'] = "{} | {}".format(self.model.__name__, self.object.name)
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
return context
|
||||
@@ -218,8 +219,8 @@ class GenericUpdateView(generic.UpdateView):
|
||||
template_name = "generic_form.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['page_title'] = f"Edit {self.model.__name__}"
|
||||
context = super(GenericUpdateView, self).get_context_data(**kwargs)
|
||||
context['page_title'] = "Edit {}".format(self.model.__name__)
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
return context
|
||||
@@ -229,8 +230,8 @@ class GenericCreateView(generic.CreateView):
|
||||
template_name = "generic_form.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['page_title'] = f"Create {self.model.__name__}"
|
||||
context = super(GenericCreateView, self).get_context_data(**kwargs)
|
||||
context['page_title'] = "Create {}".format(self.model.__name__)
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
return context
|
||||
@@ -255,13 +256,14 @@ class CloseModal(generic.TemplateView):
|
||||
class OEmbedView(generic.View):
|
||||
def get(self, request, pk=None):
|
||||
embed_url = reverse(self.url_name, args=[pk])
|
||||
full_url = f"{request.scheme}://{request.META['HTTP_HOST']}{embed_url}"
|
||||
full_url = "{0}://{1}{2}".format(request.scheme, request.META['HTTP_HOST'], embed_url)
|
||||
|
||||
data = {
|
||||
'html': f'<iframe src="{full_url}" frameborder="0" width="100%" height="250"></iframe>',
|
||||
'html': '<iframe src="{0}" frameborder="0" width="100%" height="250"></iframe>'.format(full_url),
|
||||
'version': '1.0',
|
||||
'type': 'rich',
|
||||
'height': '250'
|
||||
}
|
||||
|
||||
return JsonResponse(data)
|
||||
json = simplejson.JSONEncoderForHTML().encode(data)
|
||||
return HttpResponse(json, content_type="application/json")
|
||||
|
||||
@@ -27,7 +27,7 @@ from django.views import generic
|
||||
from z3c.rml import rml2pdf
|
||||
|
||||
from PyRIGS import decorators
|
||||
from PyRIGS.views import OEmbedView, is_ajax, ModalURLMixin
|
||||
from PyRIGS.views import OEmbedView, is_ajax
|
||||
from RIGS import models, forms
|
||||
|
||||
__author__ = 'ghost'
|
||||
@@ -53,11 +53,10 @@ class WebCalendar(generic.TemplateView):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['view'] = kwargs.get('view', '')
|
||||
context['date'] = kwargs.get('date', '')
|
||||
# context['page_title'] = "Calendar"
|
||||
return context
|
||||
|
||||
|
||||
class EventDetail(generic.DetailView, ModalURLMixin):
|
||||
class EventDetail(generic.DetailView):
|
||||
template_name = 'event_detail.html'
|
||||
model = models.Event
|
||||
|
||||
@@ -67,10 +66,6 @@ class EventDetail(generic.DetailView, ModalURLMixin):
|
||||
if self.object.dry_hire:
|
||||
title += " <span class='badge badge-secondary'>Dry Hire</span>"
|
||||
context['page_title'] = title
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
else:
|
||||
context['override'] = 'base_assets.html'
|
||||
return context
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
<script src="{% static 'js/autocompleter.js' %}"></script>
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
|
||||
{% include 'partials/datetime-fix.html' %}
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('button[data-action=add]').on('click', function (event) {
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
{% block css %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/selects.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/easymde.min.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/simplemde.min.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block preload_js %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'js/selects.js' %}"></script>
|
||||
<script src="{% static 'js/easymde.min.js' %}"></script>
|
||||
<script src="{% static 'js/simplemde.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
@@ -23,6 +23,8 @@
|
||||
<script src="{% static 'js/interaction.js' %}"></script>
|
||||
<script src="{% static 'js/tooltip.js' %}"></script>
|
||||
|
||||
{% include 'partials/datetime-fix.html' %}
|
||||
|
||||
<script>
|
||||
const matches = window.matchMedia("(prefers-reduced-motion: reduce)").matches || window.matchMedia("(update: slow)").matches;
|
||||
$(document).ready(function () {
|
||||
|
||||
@@ -180,10 +180,15 @@
|
||||
{% for item in object.items.all %}
|
||||
<tr>
|
||||
<td>
|
||||
<para>{{ item.name }}</para>
|
||||
{% if item.description %}
|
||||
{{ item.description|markdown:"rml" }}
|
||||
{% endif %}
|
||||
<para>{{ item.name }}
|
||||
{% if item.description %}
|
||||
</para>
|
||||
<para style="item_description">
|
||||
{{ item.description|markdown:"rml" }}
|
||||
</para>
|
||||
<para>
|
||||
{% endif %}
|
||||
</para>
|
||||
</td>
|
||||
<td>£{{ item.cost|floatformat:2 }}</td>
|
||||
<td>{{ item.quantity }}</td>
|
||||
@@ -203,7 +208,9 @@
|
||||
<tr>
|
||||
<td>
|
||||
{% if quote %}
|
||||
<para>This quote is valid for 30 days unless otherwise arranged.</para>
|
||||
<para>
|
||||
This quote is valid for 30 days unless otherwise arranged.
|
||||
</para>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if object.vat > 0 %}
|
||||
|
||||
@@ -9,7 +9,7 @@ register = template.Library()
|
||||
|
||||
|
||||
@register.filter(name="markdown")
|
||||
def markdown_filter(text, input_format='html', add_style=""):
|
||||
def markdown_filter(text, input_format='html'):
|
||||
# markdown library can't handle text=None
|
||||
if text is None:
|
||||
return text
|
||||
|
||||
@@ -145,11 +145,11 @@ class CreateEvent(FormPage):
|
||||
|
||||
def add_person(self):
|
||||
self.find_element(*self._add_person_selector).click()
|
||||
return regions.Modal(self, self.driver.find_element(By.ID, 'modal'))
|
||||
return regions.Modal(self, self.driver.find_element_by_id('modal'))
|
||||
|
||||
def add_event_item(self):
|
||||
self.find_element(*self._add_item_selector).click()
|
||||
element = self.driver.find_element(By.ID, 'itemModal')
|
||||
element = self.driver.find_element_by_id('itemModal')
|
||||
self.wait.until(EC.visibility_of(element))
|
||||
return rigs_regions.ItemModal(self, element)
|
||||
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
An h1 header
|
||||
============
|
||||
|
||||
Paragraphs are separated by a blank line.
|
||||
|
||||
2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists
|
||||
look like:
|
||||
|
||||
* this one
|
||||
* that one
|
||||
* the other one
|
||||
|
||||
Note that --- not considering the asterisk --- the actual text
|
||||
content starts at 4-columns in.
|
||||
|
||||
> Block quotes are
|
||||
> written like so.
|
||||
>
|
||||
> They can span multiple paragraphs,
|
||||
> if you like.
|
||||
|
||||
Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all
|
||||
in chapters 12--14"). Three dots ... will be converted to an ellipsis.
|
||||
Unicode is supported.
|
||||
|
||||
|
||||
|
||||
An h2 header
|
||||
------------
|
||||
|
||||
Here's a numbered list:
|
||||
|
||||
1. first item
|
||||
2. second item
|
||||
3. third item
|
||||
|
||||
Note again how the actual text starts at 4 columns in (4 characters
|
||||
from the left side). Here's a code sample:
|
||||
|
||||
# Let me re-iterate ...
|
||||
for i in 1 .. 10 { do-something(i) }
|
||||
|
||||
As you probably guessed, indented 4 spaces. By the way, instead of
|
||||
indenting the block, you can use delimited blocks, if you like:
|
||||
|
||||
~~~
|
||||
define foobar() {
|
||||
print "Welcome to flavor country!";
|
||||
}
|
||||
~~~
|
||||
|
||||
(which makes copying & pasting easier). You can optionally mark the
|
||||
delimited block for Pandoc to syntax highlight it:
|
||||
|
||||
~~~python
|
||||
import time
|
||||
# Quick, count to ten!
|
||||
for i in range(10):
|
||||
# (but not *too* quick)
|
||||
time.sleep(0.5)
|
||||
print i
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
### An h3 header ###
|
||||
|
||||
Now a nested list:
|
||||
|
||||
1. First, get these ingredients:
|
||||
|
||||
* carrots
|
||||
* celery
|
||||
* lentils
|
||||
|
||||
2. Boil some water.
|
||||
|
||||
3. Dump everything in the pot and follow
|
||||
this algorithm:
|
||||
|
||||
find wooden spoon
|
||||
uncover pot
|
||||
stir
|
||||
cover pot
|
||||
balance wooden spoon precariously on pot handle
|
||||
wait 10 minutes
|
||||
goto first step (or shut off burner when done)
|
||||
|
||||
Do not bump wooden spoon or it will fall.
|
||||
|
||||
Notice again how text always lines up on 4-space indents (including
|
||||
that last line which continues item 3 above).
|
||||
|
||||
Here's a link to [a website](http://foo.bar). Here's a footnote [^1].
|
||||
|
||||
[^1]: Footnote text goes here.
|
||||
|
||||
Tables can look like this:
|
||||
|
||||
size material color
|
||||
---- ------------ ------------
|
||||
9 leather brown
|
||||
10 hemp canvas natural
|
||||
11 glass transparent
|
||||
|
||||
Table: Shoes, their sizes, and what they're made of
|
||||
|
||||
(The above is the caption for the table.) Pandoc also supports
|
||||
multi-line tables:
|
||||
|
||||
-------- -----------------------
|
||||
keyword text
|
||||
-------- -----------------------
|
||||
red Sunsets, apples, and
|
||||
other red or reddish
|
||||
things.
|
||||
|
||||
green Leaves, grass, frogs
|
||||
and other things it's
|
||||
not easy being.
|
||||
-------- -----------------------
|
||||
|
||||
A horizontal rule follows.
|
||||
|
||||
***
|
||||
|
||||
Here's a definition list:
|
||||
|
||||
apples
|
||||
: Good for making applesauce.
|
||||
oranges
|
||||
: Citrus!
|
||||
tomatoes
|
||||
: There's no "e" in tomatoe.
|
||||
|
||||
Again, text is indented 4 spaces. (Put a blank line between each
|
||||
term/definition pair to spread things out more.)
|
||||
|
||||
Here's a "line block":
|
||||
|
||||
| Line one
|
||||
| Line too
|
||||
| Line tree
|
||||
|
||||
and images can be specified like so:
|
||||
|
||||

|
||||
|
||||
Inline math equations go in like so: $\\omega = d\\phi / dt$. Display
|
||||
math should get its own line and be put in in double-dollarsigns:
|
||||
|
||||
$$I = \\int \rho R^{2} dV$$
|
||||
|
||||
And note that you can backslash-escape any punctuation characters
|
||||
which you wish to be displayed literally, ex.: \\`foo\\`, \\*bar\\*, etc.
|
||||
@@ -1,8 +1,5 @@
|
||||
import os
|
||||
import pytest
|
||||
from datetime import date
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
@@ -15,6 +12,8 @@ from pytest_django.asserts import assertRedirects, assertNotContains, assertCont
|
||||
from PyRIGS.tests.base import assert_times_almost_equal, assert_oembed, login
|
||||
from RIGS import models
|
||||
|
||||
import pytest
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@@ -372,7 +371,163 @@ def test_ra_redirect(admin_client, admin_user, ra):
|
||||
|
||||
|
||||
class TestMarkdownTemplateTags(TestCase):
|
||||
markdown = open(os.path.join(settings.BASE_DIR, "RIGS/tests/sample.md")).read()
|
||||
markdown = """
|
||||
An h1 header
|
||||
============
|
||||
|
||||
Paragraphs are separated by a blank line.
|
||||
|
||||
2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists
|
||||
look like:
|
||||
|
||||
* this one
|
||||
* that one
|
||||
* the other one
|
||||
|
||||
Note that --- not considering the asterisk --- the actual text
|
||||
content starts at 4-columns in.
|
||||
|
||||
> Block quotes are
|
||||
> written like so.
|
||||
>
|
||||
> They can span multiple paragraphs,
|
||||
> if you like.
|
||||
|
||||
Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all
|
||||
in chapters 12--14"). Three dots ... will be converted to an ellipsis.
|
||||
Unicode is supported.
|
||||
|
||||
|
||||
|
||||
An h2 header
|
||||
------------
|
||||
|
||||
Here's a numbered list:
|
||||
|
||||
1. first item
|
||||
2. second item
|
||||
3. third item
|
||||
|
||||
Note again how the actual text starts at 4 columns in (4 characters
|
||||
from the left side). Here's a code sample:
|
||||
|
||||
# Let me re-iterate ...
|
||||
for i in 1 .. 10 { do-something(i) }
|
||||
|
||||
As you probably guessed, indented 4 spaces. By the way, instead of
|
||||
indenting the block, you can use delimited blocks, if you like:
|
||||
|
||||
~~~
|
||||
define foobar() {
|
||||
print "Welcome to flavor country!";
|
||||
}
|
||||
~~~
|
||||
|
||||
(which makes copying & pasting easier). You can optionally mark the
|
||||
delimited block for Pandoc to syntax highlight it:
|
||||
|
||||
~~~python
|
||||
import time
|
||||
# Quick, count to ten!
|
||||
for i in range(10):
|
||||
# (but not *too* quick)
|
||||
time.sleep(0.5)
|
||||
print i
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
### An h3 header ###
|
||||
|
||||
Now a nested list:
|
||||
|
||||
1. First, get these ingredients:
|
||||
|
||||
* carrots
|
||||
* celery
|
||||
* lentils
|
||||
|
||||
2. Boil some water.
|
||||
|
||||
3. Dump everything in the pot and follow
|
||||
this algorithm:
|
||||
|
||||
find wooden spoon
|
||||
uncover pot
|
||||
stir
|
||||
cover pot
|
||||
balance wooden spoon precariously on pot handle
|
||||
wait 10 minutes
|
||||
goto first step (or shut off burner when done)
|
||||
|
||||
Do not bump wooden spoon or it will fall.
|
||||
|
||||
Notice again how text always lines up on 4-space indents (including
|
||||
that last line which continues item 3 above).
|
||||
|
||||
Here's a link to [a website](http://foo.bar). Here's a footnote [^1].
|
||||
|
||||
[^1]: Footnote text goes here.
|
||||
|
||||
Tables can look like this:
|
||||
|
||||
size material color
|
||||
---- ------------ ------------
|
||||
9 leather brown
|
||||
10 hemp canvas natural
|
||||
11 glass transparent
|
||||
|
||||
Table: Shoes, their sizes, and what they're made of
|
||||
|
||||
(The above is the caption for the table.) Pandoc also supports
|
||||
multi-line tables:
|
||||
|
||||
-------- -----------------------
|
||||
keyword text
|
||||
-------- -----------------------
|
||||
red Sunsets, apples, and
|
||||
other red or reddish
|
||||
things.
|
||||
|
||||
green Leaves, grass, frogs
|
||||
and other things it's
|
||||
not easy being.
|
||||
-------- -----------------------
|
||||
|
||||
A horizontal rule follows.
|
||||
|
||||
***
|
||||
|
||||
Here's a definition list:
|
||||
|
||||
apples
|
||||
: Good for making applesauce.
|
||||
oranges
|
||||
: Citrus!
|
||||
tomatoes
|
||||
: There's no "e" in tomatoe.
|
||||
|
||||
Again, text is indented 4 spaces. (Put a blank line between each
|
||||
term/definition pair to spread things out more.)
|
||||
|
||||
Here's a "line block":
|
||||
|
||||
| Line one
|
||||
| Line too
|
||||
| Line tree
|
||||
|
||||
and images can be specified like so:
|
||||
|
||||

|
||||
|
||||
Inline math equations go in like so: $\\omega = d\\phi / dt$. Display
|
||||
math should get its own line and be put in in double-dollarsigns:
|
||||
|
||||
$$I = \\int \rho R^{2} dV$$
|
||||
|
||||
And note that you can backslash-escape any punctuation characters
|
||||
which you wish to be displayed literally, ex.: \\`foo\\`, \\*bar\\*, etc.
|
||||
"""
|
||||
|
||||
def test_html_safe(self):
|
||||
html = markdown_filter(self.markdown)
|
||||
@@ -401,7 +556,6 @@ class TestMarkdownTemplateTags(TestCase):
|
||||
description=self.markdown,
|
||||
start_date='2016-01-01',
|
||||
)
|
||||
event_item = models.EventItem.objects.create(event=event, name="TI I1", quantity=1, cost=1.00, order=1, description="* test \n * test \n * test")
|
||||
user = models.Profile.objects.create(
|
||||
username='RML test',
|
||||
is_superuser=True, # Don't care about permissions
|
||||
|
||||
80
RIGS/urls.py
80
RIGS/urls.py
@@ -5,7 +5,7 @@ from django.views.generic import RedirectView
|
||||
|
||||
from PyRIGS.decorators import (api_key_required, has_oembed,
|
||||
permission_required_with_403)
|
||||
from . import views
|
||||
from RIGS import finance, ical, rigboard, views, hs
|
||||
|
||||
urlpatterns = [
|
||||
# People
|
||||
@@ -42,101 +42,101 @@ urlpatterns = [
|
||||
name='venue_update'),
|
||||
|
||||
# Rigboard
|
||||
path('rigboard/', login_required(views.RigboardIndex.as_view()), name='rigboard'),
|
||||
path('rigboard/calendar/', login_required()(views.WebCalendar.as_view()),
|
||||
path('rigboard/', login_required(rigboard.RigboardIndex.as_view()), name='rigboard'),
|
||||
path('rigboard/calendar/', login_required()(rigboard.WebCalendar.as_view()),
|
||||
name='web_calendar'),
|
||||
re_path(r'^rigboard/calendar/(?P<view>(month|week|day))/$',
|
||||
login_required()(views.WebCalendar.as_view()), name='web_calendar'),
|
||||
login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
||||
re_path(r'^rigboard/calendar/(?P<view>(month|week|day))/(?P<date>(\d{4}-\d{2}-\d{2}))/$',
|
||||
login_required()(views.WebCalendar.as_view()), name='web_calendar'),
|
||||
login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
||||
path('rigboard/archive/', RedirectView.as_view(permanent=True, pattern_name='event_archive')),
|
||||
|
||||
|
||||
path('event/<int:pk>/', has_oembed(oembed_view="event_oembed")(views.EventDetail.as_view()),
|
||||
path('event/<int:pk>/', has_oembed(oembed_view="event_oembed")(rigboard.EventDetail.as_view()),
|
||||
name='event_detail'),
|
||||
path('event/create/', permission_required_with_403('RIGS.add_event')(views.EventCreate.as_view()),
|
||||
path('event/create/', permission_required_with_403('RIGS.add_event')(rigboard.EventCreate.as_view()),
|
||||
name='event_create'),
|
||||
path('event/archive/', login_required()(views.EventArchive.as_view()),
|
||||
path('event/archive/', login_required()(rigboard.EventArchive.as_view()),
|
||||
name='event_archive'),
|
||||
path('event/<int:pk>/embed/',
|
||||
xframe_options_exempt(login_required(login_url='/user/login/embed/')(views.EventEmbed.as_view())),
|
||||
xframe_options_exempt(login_required(login_url='/user/login/embed/')(rigboard.EventEmbed.as_view())),
|
||||
name='event_embed'),
|
||||
path('event/<int:pk>/oembed_json/', views.EventOEmbed.as_view(),
|
||||
path('event/<int:pk>/oembed_json/', rigboard.EventOEmbed.as_view(),
|
||||
name='event_oembed'),
|
||||
path('event/<int:pk>/print/', permission_required_with_403('RIGS.view_event')(views.EventPrint.as_view()),
|
||||
path('event/<int:pk>/print/', permission_required_with_403('RIGS.view_event')(rigboard.EventPrint.as_view()),
|
||||
name='event_print'),
|
||||
path('event/<int:pk>/edit/', permission_required_with_403('RIGS.change_event')(views.EventUpdate.as_view()),
|
||||
path('event/<int:pk>/edit/', permission_required_with_403('RIGS.change_event')(rigboard.EventUpdate.as_view()),
|
||||
name='event_update'),
|
||||
path('event/<int:pk>/duplicate/', permission_required_with_403('RIGS.add_event')(views.EventDuplicate.as_view()),
|
||||
path('event/<int:pk>/duplicate/', permission_required_with_403('RIGS.add_event')(rigboard.EventDuplicate.as_view()),
|
||||
name='event_duplicate'),
|
||||
|
||||
# Event H&S
|
||||
path('event/hs/', permission_required_with_403('RIGS.view_riskassessment')(views.HSList.as_view()), name='hs_list'),
|
||||
path('event/hs/', permission_required_with_403('RIGS.view_riskassessment')(hs.HSList.as_view()), name='hs_list'),
|
||||
|
||||
path('event/<int:pk>/ra/', permission_required_with_403('RIGS.add_riskassessment')(views.EventRiskAssessmentCreate.as_view()),
|
||||
path('event/<int:pk>/ra/', permission_required_with_403('RIGS.add_riskassessment')(hs.EventRiskAssessmentCreate.as_view()),
|
||||
name='event_ra'),
|
||||
path('event/ra/<int:pk>/', permission_required_with_403('RIGS.view_riskassessment')(views.EventRiskAssessmentDetail.as_view()),
|
||||
path('event/ra/<int:pk>/', permission_required_with_403('RIGS.view_riskassessment')(hs.EventRiskAssessmentDetail.as_view()),
|
||||
name='ra_detail'),
|
||||
path('event/ra/<int:pk>/edit/', permission_required_with_403('RIGS.change_riskassessment')(views.EventRiskAssessmentEdit.as_view()),
|
||||
path('event/ra/<int:pk>/edit/', permission_required_with_403('RIGS.change_riskassessment')(hs.EventRiskAssessmentEdit.as_view()),
|
||||
name='ra_edit'),
|
||||
path('event/ra/list', permission_required_with_403('RIGS.view_riskassessment')(views.EventRiskAssessmentList.as_view()),
|
||||
path('event/ra/list', permission_required_with_403('RIGS.view_riskassessment')(hs.EventRiskAssessmentList.as_view()),
|
||||
name='ra_list'),
|
||||
path('event/ra/<int:pk>/review/', permission_required_with_403('RIGS.review_riskassessment')(views.EventRiskAssessmentReview.as_view()),
|
||||
path('event/ra/<int:pk>/review/', permission_required_with_403('RIGS.review_riskassessment')(hs.EventRiskAssessmentReview.as_view()),
|
||||
name='ra_review'),
|
||||
|
||||
path('event/<int:pk>/checklist/', permission_required_with_403('RIGS.add_eventchecklist')(views.EventChecklistCreate.as_view()),
|
||||
path('event/<int:pk>/checklist/', permission_required_with_403('RIGS.add_eventchecklist')(hs.EventChecklistCreate.as_view()),
|
||||
name='event_ec'),
|
||||
path('event/checklist/<int:pk>/', permission_required_with_403('RIGS.view_eventchecklist')(views.EventChecklistDetail.as_view()),
|
||||
path('event/checklist/<int:pk>/', permission_required_with_403('RIGS.view_eventchecklist')(hs.EventChecklistDetail.as_view()),
|
||||
name='ec_detail'),
|
||||
path('event/checklist/<int:pk>/edit/', permission_required_with_403('RIGS.change_eventchecklist')(views.EventChecklistEdit.as_view()),
|
||||
path('event/checklist/<int:pk>/edit/', permission_required_with_403('RIGS.change_eventchecklist')(hs.EventChecklistEdit.as_view()),
|
||||
name='ec_edit'),
|
||||
path('event/checklist/list', permission_required_with_403('RIGS.view_eventchecklist')(views.EventChecklistList.as_view()),
|
||||
path('event/checklist/list', permission_required_with_403('RIGS.view_eventchecklist')(hs.EventChecklistList.as_view()),
|
||||
name='ec_list'),
|
||||
path('event/checklist/<int:pk>/review/', permission_required_with_403('RIGS.review_eventchecklist')(views.EventChecklistReview.as_view()),
|
||||
path('event/checklist/<int:pk>/review/', permission_required_with_403('RIGS.review_eventchecklist')(hs.EventChecklistReview.as_view()),
|
||||
name='ec_review'),
|
||||
|
||||
# Finance
|
||||
path('invoice/', permission_required_with_403('RIGS.view_invoice')(views.InvoiceIndex.as_view()),
|
||||
path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()),
|
||||
name='invoice_list'),
|
||||
path('invoice/archive/', permission_required_with_403('RIGS.view_invoice')(views.InvoiceArchive.as_view()),
|
||||
path('invoice/archive/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceArchive.as_view()),
|
||||
name='invoice_archive'),
|
||||
path('invoice/waiting/', permission_required_with_403('RIGS.add_invoice')(views.InvoiceWaiting.as_view()),
|
||||
path('invoice/waiting/', permission_required_with_403('RIGS.add_invoice')(finance.InvoiceWaiting.as_view()),
|
||||
name='invoice_waiting'),
|
||||
|
||||
path('event/<int:pk>/invoice/', permission_required_with_403('RIGS.add_invoice')(views.InvoiceEvent.as_view()),
|
||||
path('event/<int:pk>/invoice/', permission_required_with_403('RIGS.add_invoice')(finance.InvoiceEvent.as_view()),
|
||||
name='invoice_event'),
|
||||
path('event/<int:pk>/invoice/void', permission_required_with_403('RIGS.add_invoice')(views.InvoiceEvent.as_view()),
|
||||
path('event/<int:pk>/invoice/void', permission_required_with_403('RIGS.add_invoice')(finance.InvoiceEvent.as_view()),
|
||||
name='invoice_event_void', kwargs={'void': True}),
|
||||
|
||||
path('invoice/<int:pk>/', permission_required_with_403('RIGS.view_invoice')(views.InvoiceDetail.as_view()),
|
||||
path('invoice/<int:pk>/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceDetail.as_view()),
|
||||
name='invoice_detail'),
|
||||
path('invoice/<int:pk>/print/', permission_required_with_403('RIGS.view_invoice')(views.InvoicePrint.as_view()),
|
||||
path('invoice/<int:pk>/print/', permission_required_with_403('RIGS.view_invoice')(finance.InvoicePrint.as_view()),
|
||||
name='invoice_print'),
|
||||
path('invoice/<int:pk>/void/', permission_required_with_403('RIGS.change_invoice')(views.InvoiceVoid.as_view()),
|
||||
path('invoice/<int:pk>/void/', permission_required_with_403('RIGS.change_invoice')(finance.InvoiceVoid.as_view()),
|
||||
name='invoice_void'),
|
||||
path('invoice/<int:pk>/delete/',
|
||||
permission_required_with_403('RIGS.change_invoice')(views.InvoiceDelete.as_view()),
|
||||
permission_required_with_403('RIGS.change_invoice')(finance.InvoiceDelete.as_view()),
|
||||
name='invoice_delete'),
|
||||
|
||||
path('payment/create/', permission_required_with_403('RIGS.add_payment')(views.PaymentCreate.as_view()),
|
||||
path('payment/create/', permission_required_with_403('RIGS.add_payment')(finance.PaymentCreate.as_view()),
|
||||
name='payment_create'),
|
||||
path('payment/<int:pk>/delete/', permission_required_with_403('RIGS.add_payment')(views.PaymentDelete.as_view()),
|
||||
path('payment/<int:pk>/delete/', permission_required_with_403('RIGS.add_payment')(finance.PaymentDelete.as_view()),
|
||||
name='payment_delete'),
|
||||
|
||||
# Client event authorisation
|
||||
path('event/<pk>/auth/',
|
||||
permission_required_with_403('RIGS.change_event')(views.EventAuthorisationRequest.as_view()),
|
||||
permission_required_with_403('RIGS.change_event')(rigboard.EventAuthorisationRequest.as_view()),
|
||||
name='event_authorise_request'),
|
||||
path('event/<int:pk>/auth/preview/',
|
||||
permission_required_with_403('RIGS.change_event')(views.EventAuthoriseRequestEmailPreview.as_view()),
|
||||
permission_required_with_403('RIGS.change_event')(rigboard.EventAuthoriseRequestEmailPreview.as_view()),
|
||||
name='event_authorise_preview'),
|
||||
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/$', views.EventAuthorise.as_view(),
|
||||
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/$', rigboard.EventAuthorise.as_view(),
|
||||
name='event_authorise'),
|
||||
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/preview/$', views.EventAuthorise.as_view(preview=True),
|
||||
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/preview/$', rigboard.EventAuthorise.as_view(preview=True),
|
||||
name='event_authorise_form_preview'),
|
||||
|
||||
# ICS Calendar - API key authentication
|
||||
re_path(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(views.CalendarICS()),
|
||||
re_path(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(ical.CalendarICS()),
|
||||
name="ics_calendar"),
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
from .crud import *
|
||||
from .finance import *
|
||||
from .hs import *
|
||||
from .ical import *
|
||||
from .rigboard import *
|
||||
@@ -189,7 +189,3 @@ class Asset(models.Model, RevisionMixin):
|
||||
@property
|
||||
def display_id(self):
|
||||
return str(self.asset_id)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return f"{self.display_id} | {self.description}"
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
{% block css %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" href="{% static 'css/selects.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/easymde.min.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/simplemde.min.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block preload_js %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'js/selects.js' %}"></script>
|
||||
<script src="{% static 'js/easymde.min.js' %}"></script>
|
||||
<script src="{% static 'js/simplemde.min.js' %}"></script>
|
||||
<script src="{% static 'js/interaction.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -31,8 +31,48 @@
|
||||
checkIfCableHidden();
|
||||
</script>
|
||||
<script>
|
||||
$('document').ready(function(){
|
||||
$(document).find(".selectpicker").selectpicker().each(function(){initPicker($(this))});
|
||||
$('#parent_id')
|
||||
.selectpicker({
|
||||
liveSearch: true
|
||||
})
|
||||
.ajaxSelectPicker({
|
||||
ajax: {
|
||||
url: "{% url 'asset_search_json' %}",
|
||||
type: "GET",
|
||||
data: function () {
|
||||
let params = {
|
||||
{% verbatim %}query: '{{{q}}}'{% endverbatim %}
|
||||
};
|
||||
return params;
|
||||
}
|
||||
},
|
||||
locale: {
|
||||
emptyTitle: 'Search for item...'
|
||||
},
|
||||
preprocessData: function(data){
|
||||
var assets = [];
|
||||
if(data.length){
|
||||
var len = data.length;
|
||||
for(var i = 0; i < len; i++){
|
||||
var curr = data[i];
|
||||
assets.push(
|
||||
{
|
||||
'value': curr.id,
|
||||
'text': curr.label,
|
||||
'disabled': false
|
||||
}
|
||||
);
|
||||
}
|
||||
assets.push(
|
||||
{
|
||||
'value': null,
|
||||
'text': "No parent"
|
||||
});
|
||||
}
|
||||
|
||||
return assets;
|
||||
},
|
||||
preserveSelected: false
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{% if create or edit or duplicate %}
|
||||
<div class="form-group" id="parent-group">
|
||||
<label for="selectpicker">Set Parent</label>
|
||||
<select name="parent" id="parent_id" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='asset' %}?fields=asset_id,description">
|
||||
<select name="parent" id="parent_id" class="form-control selectpicker" data-live-search="true">
|
||||
{% if object.parent %}
|
||||
<option value="{{object.parent.pk}}" selected>{{object.parent.description}}</option>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from django.utils import timezone
|
||||
@@ -139,11 +138,11 @@ class TestAssetForm(AutoLoginTest):
|
||||
|
||||
self.page.parent_selector.toggle()
|
||||
self.assertTrue(self.page.parent_selector.is_open)
|
||||
option = self.parent.asset_id
|
||||
option = str(self.parent)
|
||||
self.page.parent_selector.search(option)
|
||||
time.sleep(2) # Slow down for javascript
|
||||
# self.page.parent_selector.set_option(option, True)
|
||||
# self.assertTrue(self.page.parent_selector.options[0].selected)
|
||||
self.driver.implicitly_wait(1)
|
||||
self.page.parent_selector.set_option(option, True)
|
||||
self.assertTrue(self.page.parent_selector.options[0].selected)
|
||||
self.page.parent_selector.toggle()
|
||||
|
||||
self.assertFalse(self.driver.find_element_by_id('cable-table').is_displayed())
|
||||
|
||||
@@ -27,6 +27,7 @@ urlpatterns = [
|
||||
path('cabletype/<int:pk>/update/', permission_required_with_403('assets.change_cable_type')(views.CableTypeUpdate.as_view()), name='cable_type_update'),
|
||||
path('cabletype/<int:pk>/detail/', login_required(views.CableTypeDetail.as_view()), name='cable_type_detail'),
|
||||
|
||||
path('asset/search/', login_required(views.AssetSearch.as_view()), name='asset_search_json'),
|
||||
path('asset/id/<str:pk>/embed/',
|
||||
xframe_options_exempt(
|
||||
login_required(login_url='/user/login/embed/')(views.AssetEmbed.as_view())),
|
||||
@@ -42,4 +43,6 @@ urlpatterns = [
|
||||
(views.SupplierCreate.as_view()), name='supplier_create'),
|
||||
path('supplier/<int:pk>/edit/', permission_required_with_403('assets.change_supplier')
|
||||
(views.SupplierUpdate.as_view()), name='supplier_update'),
|
||||
|
||||
path('supplier/search/', login_required(views.SupplierSearch.as_view()), name='supplier_search_json'),
|
||||
]
|
||||
|
||||
@@ -87,10 +87,28 @@ class AssetList(LoginRequiredMixin, generic.ListView):
|
||||
return context
|
||||
|
||||
|
||||
class AssetSearch(AssetList):
|
||||
hide_hidden_status = False
|
||||
|
||||
def render_to_response(self, context, **response_kwargs):
|
||||
result = []
|
||||
|
||||
for asset in context["object_list"]:
|
||||
result.append({"id": asset.pk, "label": (asset.asset_id + " | " + asset.description)})
|
||||
|
||||
return JsonResponse(result, safe=False)
|
||||
|
||||
|
||||
class AssetIDUrlMixin:
|
||||
def get_object(self, queryset=None):
|
||||
pk = self.kwargs.get(self.pk_url_kwarg)
|
||||
return get_object_or_404(models.Asset, asset_id=pk)
|
||||
queryset = models.Asset.objects.filter(asset_id=pk)
|
||||
try:
|
||||
# Get the single item from the filtered queryset
|
||||
obj = queryset.get()
|
||||
except queryset.model.DoesNotExist:
|
||||
raise Http404("No assets found matching the query")
|
||||
return obj
|
||||
|
||||
|
||||
class AssetDetail(LoginRequiredMixin, AssetIDUrlMixin, generic.DetailView):
|
||||
@@ -176,6 +194,7 @@ class AssetOEmbed(OEmbedView):
|
||||
|
||||
class AssetAuditList(AssetList):
|
||||
template_name = 'asset_audit_list.html'
|
||||
hide_hidden_status = False
|
||||
|
||||
# TODO Refresh this when the modal is submitted
|
||||
def get_queryset(self):
|
||||
@@ -223,6 +242,17 @@ class SupplierList(GenericListView):
|
||||
return context
|
||||
|
||||
|
||||
class SupplierSearch(SupplierList):
|
||||
hide_hidden_status = False
|
||||
|
||||
def render_to_response(self, context, **response_kwargs):
|
||||
result = []
|
||||
|
||||
for supplier in context["object_list"]:
|
||||
result.append({"id": supplier.pk, "name": supplier.name})
|
||||
return JsonResponse(result, safe=False)
|
||||
|
||||
|
||||
class SupplierDetail(GenericDetailView):
|
||||
model = models.Supplier
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ function styles(done) {
|
||||
'node_modules/fullcalendar/main.css',
|
||||
'node_modules/bootstrap-select/dist/css/bootstrap-select.css',
|
||||
'node_modules/ajax-bootstrap-select/dist/css/ajax-bootstrap-select.css',
|
||||
'node_modules/easymde/dist/easymde.min.css'
|
||||
'node_modules/flatpickr/dist/flatpickr.css',
|
||||
'node_modules/simplemde/dist/simplemde.min.css'
|
||||
])
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
@@ -58,11 +59,12 @@ function scripts() {
|
||||
|
||||
'node_modules/html5sortable/dist/html5sortable.min.js',
|
||||
'node_modules/clipboard/dist/clipboard.min.js',
|
||||
'node_modules/flatpickr/dist/flatpickr.min.js',
|
||||
'node_modules/moment/moment.js',
|
||||
'node_modules/fullcalendar/main.js',
|
||||
'node_modules/bootstrap-select/dist/js/bootstrap-select.js',
|
||||
'node_modules/ajax-bootstrap-select/dist/js/ajax-bootstrap-select.js',
|
||||
'node_modules/easymde/dist/easymde.min.js',
|
||||
'node_modules/simplemde/dist/simplemde.min.js',
|
||||
'node_modules/konami/konami.js',
|
||||
'pipeline/source_assets/js/**/*.js',])
|
||||
.pipe(gulpif(function(file) { return base_scripts.includes(file.relative);}, con('base.js')))
|
||||
|
||||
185
package-lock.json
generated
185
package-lock.json
generated
@@ -13,11 +13,11 @@
|
||||
"ajax-bootstrap-select": "^1.4.5",
|
||||
"autocompleter": "^6.1.2",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bootstrap-select": "^1.13.17",
|
||||
"clipboard": "^2.0.8",
|
||||
"cssnano": "^5.0.13",
|
||||
"easymde": "^2.16.1",
|
||||
"flatpickr": "^4.6.6",
|
||||
"fullcalendar": "^5.10.1",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
@@ -34,6 +34,7 @@
|
||||
"node-sass": "^7.0.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"postcss": "^8.4.5",
|
||||
"simplemde": "^1.11.2",
|
||||
"uglify-js": "^3.14.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -255,24 +256,6 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/codemirror": {
|
||||
"version": "5.60.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.5.tgz",
|
||||
"integrity": "sha512-TiECZmm8St5YxjFUp64LK0c8WU5bxMDt9YaAek1UqUb9swrSCoJhh92fWu1p3mTEqlHjhB5sY7OFBhWroJXZVg==",
|
||||
"dependencies": {
|
||||
"@types/tern": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "0.0.50",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
|
||||
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
|
||||
},
|
||||
"node_modules/@types/marked": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
|
||||
"integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag=="
|
||||
},
|
||||
"node_modules/@types/minimist": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
|
||||
@@ -283,14 +266,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
||||
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
||||
},
|
||||
"node_modules/@types/tern": {
|
||||
"version": "0.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz",
|
||||
"integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==",
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
@@ -957,17 +932,9 @@
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
|
||||
"integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jquery": "1.9.1 - 3",
|
||||
"popper.js": "^1.16.1"
|
||||
}
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw=="
|
||||
},
|
||||
"node_modules/bootstrap-select": {
|
||||
"version": "1.13.18",
|
||||
@@ -1612,20 +1579,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/copy-props": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz",
|
||||
"integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
|
||||
"integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
|
||||
"dependencies": {
|
||||
"each-props": "^1.3.2",
|
||||
"is-plain-object": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-props/node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
"each-props": "^1.3.0",
|
||||
"is-plain-object": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
@@ -2067,18 +2026,6 @@
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/easymde": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz",
|
||||
"integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==",
|
||||
"dependencies": {
|
||||
"@types/codemirror": "^5.60.4",
|
||||
"@types/marked": "^4.0.1",
|
||||
"codemirror": "^5.63.1",
|
||||
"codemirror-spell-checker": "1.1.2",
|
||||
"marked": "^4.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/eazy-logger": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz",
|
||||
@@ -2788,6 +2735,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
},
|
||||
"node_modules/flush-write-stream": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
|
||||
@@ -2798,23 +2750,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"version": "1.14.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
|
||||
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/for-in": {
|
||||
@@ -4927,9 +4868,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
|
||||
"integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.8.tgz",
|
||||
"integrity": "sha512-dkpJMIlJpc833hbjjg8jraw1t51e/eKDoG8TFOgc5O0Z77zaYKigYekTDop5AplRoKFGIaoazhYEhGkMtU3IeA==",
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
},
|
||||
@@ -5500,9 +5441,9 @@
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
@@ -7377,6 +7318,16 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
|
||||
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
|
||||
},
|
||||
"node_modules/simplemde": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/simplemde/-/simplemde-1.11.2.tgz",
|
||||
"integrity": "sha1-ojo12XjSxA7wfewAjJLwcNjggOM=",
|
||||
"dependencies": {
|
||||
"codemirror": "*",
|
||||
"codemirror-spell-checker": "*",
|
||||
"marked": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
@@ -9162,24 +9113,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="
|
||||
},
|
||||
"@types/codemirror": {
|
||||
"version": "5.60.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.5.tgz",
|
||||
"integrity": "sha512-TiECZmm8St5YxjFUp64LK0c8WU5bxMDt9YaAek1UqUb9swrSCoJhh92fWu1p3mTEqlHjhB5sY7OFBhWroJXZVg==",
|
||||
"requires": {
|
||||
"@types/tern": "*"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.50",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
|
||||
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
|
||||
},
|
||||
"@types/marked": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
|
||||
"integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag=="
|
||||
},
|
||||
"@types/minimist": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
|
||||
@@ -9190,14 +9123,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
|
||||
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
||||
},
|
||||
"@types/tern": {
|
||||
"version": "0.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz",
|
||||
"integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==",
|
||||
"requires": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
@@ -9709,10 +9634,9 @@
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz",
|
||||
"integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==",
|
||||
"requires": {}
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw=="
|
||||
},
|
||||
"bootstrap-select": {
|
||||
"version": "1.13.18",
|
||||
@@ -10627,18 +10551,6 @@
|
||||
"lodash": "^4.17.10"
|
||||
}
|
||||
},
|
||||
"easymde": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz",
|
||||
"integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==",
|
||||
"requires": {
|
||||
"@types/codemirror": "^5.60.4",
|
||||
"@types/marked": "^4.0.1",
|
||||
"codemirror": "^5.63.1",
|
||||
"codemirror-spell-checker": "1.1.2",
|
||||
"marked": "^4.0.10"
|
||||
}
|
||||
},
|
||||
"eazy-logger": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz",
|
||||
@@ -11251,6 +11163,11 @@
|
||||
"resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
|
||||
"integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="
|
||||
},
|
||||
"flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
},
|
||||
"flush-write-stream": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
|
||||
@@ -13431,9 +13348,9 @@
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA=="
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
@@ -14893,6 +14810,16 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
|
||||
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
|
||||
},
|
||||
"simplemde": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/simplemde/-/simplemde-1.11.2.tgz",
|
||||
"integrity": "sha1-ojo12XjSxA7wfewAjJLwcNjggOM=",
|
||||
"requires": {
|
||||
"codemirror": "*",
|
||||
"codemirror-spell-checker": "*",
|
||||
"marked": "*"
|
||||
}
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
"ajax-bootstrap-select": "^1.4.5",
|
||||
"autocompleter": "^6.1.2",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bootstrap-select": "^1.13.17",
|
||||
"clipboard": "^2.0.8",
|
||||
"cssnano": "^5.0.13",
|
||||
"easymde": "^2.16.1",
|
||||
"flatpickr": "^4.6.6",
|
||||
"fullcalendar": "^5.10.1",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
@@ -31,6 +31,7 @@
|
||||
"node-sass": "^7.0.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"postcss": "^8.4.5",
|
||||
"simplemde": "^1.11.2",
|
||||
"uglify-js": "^3.14.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
marked.setOptions({
|
||||
breaks: true,
|
||||
})
|
||||
|
||||
function setupItemTable(items_json) {
|
||||
objectitems = JSON.parse(items_json)
|
||||
$.each(objectitems, function (key, val) {
|
||||
@@ -33,8 +37,7 @@ function updatePrices() {
|
||||
}
|
||||
|
||||
function setupMDE(selector) {
|
||||
editor = new EasyMDE({
|
||||
autoDownloadFontAwesome: false,
|
||||
editor = new SimpleMDE({
|
||||
element: $(selector)[0],
|
||||
forceSync: true,
|
||||
toolbar: ["bold", "italic", "strikethrough", "|", "unordered-list", "ordered-list", "|", "link", "|", "preview", "guide"],
|
||||
@@ -117,7 +120,7 @@ $('body').on('submit', '#item-form', function (e) {
|
||||
// update the table
|
||||
$row = $('#item-' + pk);
|
||||
$row.find('.name').html(escapeHtml(fields.name));
|
||||
$row.find('.description').html(fields.description);
|
||||
$row.find('.description').html(marked(fields.description));
|
||||
$row.find('.cost').html(parseFloat(fields.cost).toFixed(2));
|
||||
$row.find('.quantity').html(fields.quantity);
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
color: $gray-100;
|
||||
}
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:focus,
|
||||
textarea:-webkit-autofill,
|
||||
textarea:-webkit-autofill:hover,
|
||||
@@ -145,7 +145,7 @@
|
||||
.editor-toolbar > a.active {
|
||||
background: $info !important;
|
||||
}
|
||||
.cm-s-easymde {
|
||||
.cm-s-paper {
|
||||
color: white;
|
||||
background-color: $darktheme;
|
||||
border-color: #bbb;
|
||||
@@ -153,7 +153,4 @@
|
||||
.CodeMirror-cursor {
|
||||
border-color: white !important;
|
||||
}
|
||||
.modal {
|
||||
overflow-y: auto !important; //Bootstrap Dark Theme overrides this to none for some insane reason so we need to change it back
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,10 @@ textarea {
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
z-index: inherit; // bug fix introduced in 52682ce
|
||||
}
|
||||
|
||||
del {
|
||||
background-color: #f2dede;
|
||||
border-radius: 3px;
|
||||
|
||||
21
templates/analytics.html
Normal file
21
templates/analytics.html
Normal file
@@ -0,0 +1,21 @@
|
||||
{% if not debug %}
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
ga('create', 'UA-43285686-12', 'auto');
|
||||
{% if user.is_authenticated %}
|
||||
ga('set', '&uid', {{ user.pk }});
|
||||
{% endif %}
|
||||
ga('require', 'linkid', 'linkid.js');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
{% endif %}
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
<body>
|
||||
<a class="skip-link" href='#main'>Skip to content</a>
|
||||
{% include "analytics.html" %}
|
||||
{% block navbar %}
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" role="navigation">
|
||||
<div class="container">
|
||||
@@ -78,6 +79,7 @@
|
||||
<div class="modal fade" id="modal" role="dialog" tabindex=-1></div>
|
||||
|
||||
<script src="{% static 'js/base.js' %}"></script>
|
||||
<script src="{% static 'js/marked.min.js' %}"></script>
|
||||
{% include 'partials/dark_theme.html' %}
|
||||
|
||||
{% block js %}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include "analytics.html" %}
|
||||
<div class="embed_container">
|
||||
<div class="container-fluid">
|
||||
{% if messages %}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<h2 class="col-sm-12 pb-3">Welcome back {{ user.get_full_name }}, there {%if rig_count == 1 %}is one rig coming up{%else%}are {{ rig_count|apnumber }} rigs coming up.{%endif%}</h2>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<div class="card">
|
||||
<img class="card-img-top d-none d-sm-block" src="{% static 'imgs/rigs.jpg' %}" alt="Some lights and haze, very purple" style="height: 150px; object-fit: cover;">
|
||||
<img class="card-img-top" src="{% static 'imgs/rigs.jpg' %}" alt="" style="height: 150px; object-fit: cover;">
|
||||
<h4 class="card-header">Rigboard</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'rigboard' %}"><span class="fas fa-list align-middle"></span><span class="align-middle"> Rigboard</span></a>
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="col-sm-4 mb-3">
|
||||
<div class="card">
|
||||
{% now "m-d" as todays_date %}
|
||||
<img class="card-img-top d-none d-sm-block" src="{% if todays_date == '04-01' %}{% static 'imgs/tappytaptap.gif' %}{%else%}{% static 'imgs/assets.jpg' %}{%endif%}" alt="M32 sound desk close up of the faders" style="height: 150px; object-fit: cover;">
|
||||
<img class="card-img-top" src="{% if todays_date == '04-01' %}{% static 'imgs/tappytaptap.gif' %}{%else%}{% static 'imgs/assets.jpg' %}{%endif%}" alt="" style="height: 150px; object-fit: cover;">
|
||||
<h4 class="card-header">Asset Database</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'asset_index' %}"><span class="fas fa-tag align-middle"></span><span class="align-middle"> Asset List</span></a>
|
||||
@@ -40,7 +40,7 @@
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<div class="card">
|
||||
<img class="card-img-top d-none d-sm-block" src="{% static 'imgs/training.jpg' %}" alt="People watching a presentation" style="height: 150px; object-fit: cover;">
|
||||
<img class="card-img-top" src="{% static 'imgs/training.jpg' %}" alt="" style="height: 150px; object-fit: cover;">
|
||||
<h4 class="card-header">Training Database</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action text-info" href="{% url 'trainee_detail' request.user.pk %}"><span class="fas fa-file-signature align-middle"></span><span class="align-middle"> My Training Record</span></a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static %}
|
||||
<script>
|
||||
if({{ request.user.dark_theme|lower|default:'false' }} || window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.querySelector('head').innerHTML += '<link rel="stylesheet" href="{% static "css/dark_screen.css" %}" type="text/css"/>';
|
||||
$('<link>').prependTo('head').attr({type : 'text/css', rel : 'stylesheet'}).attr('href', '{% static "css/dark_screen.css" %}');
|
||||
document.body.setAttribute('data-theme', 'dark');
|
||||
}
|
||||
</script>
|
||||
|
||||
34
templates/partials/datetime-fix.html
Normal file
34
templates/partials/datetime-fix.html
Normal file
@@ -0,0 +1,34 @@
|
||||
{% load static %}
|
||||
<script>
|
||||
function initDatetime() {
|
||||
$('input[type=datetime-local]').not(':disabled').flatpickr({
|
||||
dateFormat: 'Y-m-dTH:m',
|
||||
enableTime: true,
|
||||
allowInput: true,
|
||||
altInput: true,
|
||||
altFormat: "d/m/y H:m",
|
||||
});
|
||||
}
|
||||
$(document).ready(function () {
|
||||
function supportsDateTime() {
|
||||
var input = document.createElement('input');
|
||||
input.setAttribute('type','datetime-local');
|
||||
return input.type !== "text";
|
||||
}
|
||||
//Firefox reports support for datetime-local without properly supporting it. Bah.
|
||||
if(!supportsDateTime() || navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
|
||||
$('<link>')
|
||||
.appendTo('head')
|
||||
.attr({type : 'text/css', rel : 'stylesheet'})
|
||||
.attr('href', '{% static "css/flatpickr.css" %}');
|
||||
$.when(
|
||||
$.getScript( '{% static "js/flatpickr.min.js" %}' ),
|
||||
$.Deferred(function(deferred){
|
||||
$(deferred.resolve);
|
||||
})
|
||||
).done(function(){
|
||||
initDatetime();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -96,14 +96,14 @@ class TrainingItemQualification(models.Model, RevisionMixin):
|
||||
# TODO Maximum depth - some things stop at Complete and you can't be passed out in them
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.get_depth_display()} in {self.item} on {self.date.strftime('%b %d %Y')}"
|
||||
return "{} in {} on {}".format(self.get_depth_display(), self.item, self.date.strftime("%b %d %Y"))
|
||||
|
||||
@property
|
||||
def activity_feed_string(self):
|
||||
return f"{self.get_depth_display()} in {self.item}"
|
||||
return str("{} in {}".format(self.get_depth_display(), self.item))
|
||||
|
||||
@classmethod
|
||||
def get_colour_from_depth(cls, depth):
|
||||
def get_colour_from_depth(cls, obj, depth):
|
||||
if depth == 0:
|
||||
return "warning"
|
||||
if depth == 1:
|
||||
@@ -238,8 +238,7 @@ class TrainingLevelRequirement(models.Model, RevisionMixin):
|
||||
reversion_hide = True
|
||||
|
||||
def __str__(self):
|
||||
depth = TrainingItemQualification.CHOICES[self.depth][1]
|
||||
return f"{depth} in {self.item}"
|
||||
return "{} in {}".format(TrainingItemQualification.CHOICES[self.depth][1], self.item)
|
||||
|
||||
class Meta:
|
||||
unique_together = ["level", "item"]
|
||||
|
||||
@@ -35,7 +35,7 @@ def colour_from_depth(depth):
|
||||
|
||||
@register.filter
|
||||
def get_levels_of_depth(trainee, level):
|
||||
return trainee.level_qualifications.all().exclude(confirmed_on=None).exclude(level__department=None).exclude(level__department=models.TrainingLevel.HAULAGE).select_related('level').filter(level__level=level)
|
||||
return trainee.level_qualifications.all().exclude(confirmed_on=None).exclude(level__department=models.TrainingLevel.HAULAGE).select_related('level').filter(level__level=level)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
|
||||
@@ -36,10 +36,3 @@ def test_trainee_detail(admin_client, trainee, admin_user):
|
||||
assertNotContains(response, "Your")
|
||||
name = trainee.first_name + " " + trainee.last_name
|
||||
assertContains(response, f"{name}'s Training Record")
|
||||
|
||||
|
||||
def test_trainee_item_detail(admin_client, trainee):
|
||||
url = reverse('trainee_item_detail', kwargs={'pk': trainee.pk})
|
||||
response = admin_client.get(url)
|
||||
assert response.status_code == 200
|
||||
assertContains(response, "Nothing found")
|
||||
|
||||
Reference in New Issue
Block a user