github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/app/serializers/job.js (about) 1 import { assign } from '@ember/polyfills'; 2 import ApplicationSerializer from './application'; 3 import queryString from 'query-string'; 4 5 export default class JobSerializer extends ApplicationSerializer { 6 attrs = { 7 parameterized: 'ParameterizedJob', 8 }; 9 10 separateNanos = ['SubmitTime']; 11 12 normalize(typeHash, hash) { 13 hash.NamespaceID = hash.Namespace; 14 15 // ID is a composite of both the job ID and the namespace the job is in 16 hash.PlainId = hash.ID; 17 hash.ID = JSON.stringify([hash.ID, hash.NamespaceID || 'default']); 18 19 // ParentID comes in as "" instead of null 20 if (!hash.ParentID) { 21 hash.ParentID = null; 22 } else { 23 hash.ParentID = JSON.stringify([hash.ParentID, hash.NamespaceID || 'default']); 24 } 25 26 // Job Summary is always at /:job-id/summary, but since it can also come from 27 // the job list, it's better for Ember Data to be linked by ID association. 28 hash.SummaryID = hash.ID; 29 30 // Periodic is a boolean on list and an object on single 31 if (hash.Periodic instanceof Object) { 32 hash.PeriodicDetails = hash.Periodic; 33 hash.Periodic = true; 34 } 35 36 // Parameterized behaves like Periodic 37 if (hash.ParameterizedJob instanceof Object) { 38 hash.ParameterizedDetails = hash.ParameterizedJob; 39 hash.ParameterizedJob = true; 40 } 41 42 // If the hash contains summary information, push it into the store 43 // as a job-summary model. 44 if (hash.JobSummary) { 45 this.store.pushPayload('job-summary', { 46 'job-summary': [hash.JobSummary], 47 }); 48 } 49 50 return super.normalize(typeHash, hash); 51 } 52 53 extractRelationships(modelClass, hash) { 54 const namespace = 55 !hash.NamespaceID || hash.NamespaceID === 'default' ? undefined : hash.NamespaceID; 56 const { modelName } = modelClass; 57 58 const apiNamespace = this.store.adapterFor(modelClass.modelName).get('namespace'); 59 60 const [jobURL] = this.store 61 .adapterFor(modelName) 62 .buildURL(modelName, hash.ID, hash, 'findRecord') 63 .split('?'); 64 65 return assign(super.extractRelationships(...arguments), { 66 allocations: { 67 links: { 68 related: buildURL(`${jobURL}/allocations`, { namespace }), 69 }, 70 }, 71 versions: { 72 links: { 73 related: buildURL(`${jobURL}/versions`, { namespace, diffs: true }), 74 }, 75 }, 76 deployments: { 77 links: { 78 related: buildURL(`${jobURL}/deployments`, { namespace }), 79 }, 80 }, 81 latestDeployment: { 82 links: { 83 related: buildURL(`${jobURL}/deployment`, { namespace }), 84 }, 85 }, 86 evaluations: { 87 links: { 88 related: buildURL(`${jobURL}/evaluations`, { namespace }), 89 }, 90 }, 91 scaleState: { 92 links: { 93 related: buildURL(`${jobURL}/scale`, { namespace }), 94 }, 95 }, 96 recommendationSummaries: { 97 links: { 98 related: buildURL(`/${apiNamespace}/recommendations`, { 99 job: hash.PlainId, 100 namespace: hash.NamespaceID || 'default', 101 }), 102 }, 103 }, 104 }); 105 } 106 } 107 108 function buildURL(path, queryParams) { 109 const qpString = queryString.stringify(queryParams); 110 if (qpString) { 111 return `${path}?${qpString}`; 112 } 113 return path; 114 }