You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 line
9.5KB

  1. <script>
  2. window.__jobTypes = <?= json_encode($model->jobTypes, JSON_HEX_TAG | JSON_THROW_ON_ERROR) ?>;
  3. window.__initialJtId = <?= json_encode($model->form['job_type_id'], JSON_HEX_TAG | JSON_THROW_ON_ERROR) ?>;
  4. window.__initialJtVals = <?= json_encode($model->form['attribute_values'], JSON_HEX_TAG | JSON_THROW_ON_ERROR) ?>;
  5. </script>
  6. <section class="content-stack">
  7. <div class="page-toolbar">
  8. <div class="section-heading">
  9. <h1><?= e($model->title) ?></h1>
  10. <p>Select a campaign and job type, then fill in the attribute values.</p>
  11. </div>
  12. <a class="button button-secondary" href="/jobs">&larr; Back to list</a>
  13. </div>
  14. <?php if (!$model->campaigns): ?>
  15. <div class="alert alert-error">
  16. No campaigns exist yet. <a href="/campaigns/create">Create a campaign</a> before adding jobs.
  17. </div>
  18. <?php elseif (!$model->jobTypes): ?>
  19. <div class="alert alert-error">
  20. No job types exist yet. <a href="/job-types/create">Create a job type</a> before adding jobs.
  21. </div>
  22. <?php else: ?>
  23. <section class="section-panel" x-data="jobForm(window.__jobTypes, window.__initialJtId, window.__initialJtVals)">
  24. <?php if (isset($model->errors['_token'])): ?>
  25. <div class="alert alert-error"><?= e($model->errors['_token'][0]) ?></div>
  26. <?php endif; ?>
  27. <form method="post" action="/jobs" class="ct-form" novalidate>
  28. <?= csrf_field() ?>
  29. <div class="form-section">
  30. <label class="field field-full">
  31. <span>Campaign <span class="required-mark">*</span></span>
  32. <select class="input<?= isset($model->errors['campaign_id']) ? ' input-error' : '' ?>"
  33. name="campaign_id" required>
  34. <option value="0">— Select a campaign —</option>
  35. <?php foreach ($model->campaigns as $c): ?>
  36. <option value="<?= e((string) $c['id']) ?>"
  37. <?= (int) $model->form['campaign_id'] === (int) $c['id'] ? 'selected' : '' ?>>
  38. <?= e($c['campaign_type_name']) ?> #<?= e((string) $c['id']) ?>
  39. </option>
  40. <?php endforeach; ?>
  41. </select>
  42. <?php if (isset($model->errors['campaign_id'])): ?>
  43. <small class="field-error"><?= e($model->errors['campaign_id'][0]) ?></small>
  44. <?php endif; ?>
  45. </label>
  46. <label class="field field-full">
  47. <span>Job type <span class="required-mark">*</span></span>
  48. <select class="input<?= isset($model->errors['job_type_id']) ? ' input-error' : '' ?>"
  49. name="job_type_id" x-model="selectedTypeId" x-on:change="onTypeChange()" required>
  50. <option value="0">— Select a job type —</option>
  51. <?php foreach ($model->jobTypes as $jt): ?>
  52. <option value="<?= e((string) $jt['id']) ?>"
  53. <?= (int) $model->form['job_type_id'] === $jt['id'] ? 'selected' : '' ?>>
  54. <?= e($jt['name']) ?>
  55. </option>
  56. <?php endforeach; ?>
  57. </select>
  58. <?php if (isset($model->errors['job_type_id'])): ?>
  59. <small class="field-error"><?= e($model->errors['job_type_id'][0]) ?></small>
  60. <?php endif; ?>
  61. </label>
  62. </div>
  63. <div class="form-section" x-show="currentAttributes.length > 0">
  64. <div class="attributes-header">
  65. <h3>Attribute values</h3>
  66. <p class="attributes-hint">Fields defined by the selected job type.</p>
  67. </div>
  68. <div class="form-grid">
  69. <template x-for="attr in currentAttributes" :key="attr.name">
  70. <label class="field" :class="{ 'api-lookup-label': attr.type === 'api_lookup' || attr.type === 'customer_lookup' }">
  71. <span x-text="attr.name"></span>
  72. <template x-if="attr.type === 'boolean'">
  73. <select class="input"
  74. :name="`attribute_values[${attr.name}]`"
  75. x-on:change="attributeValues[attr.name] = $event.target.value">
  76. <option value="" :selected="!attributeValues[attr.name]">— Select —</option>
  77. <option value="true" :selected="attributeValues[attr.name] === 'true'">True</option>
  78. <option value="false" :selected="attributeValues[attr.name] === 'false'">False</option>
  79. </select>
  80. </template>
  81. <template x-if="attr.type === 'api_lookup' || attr.type === 'customer_lookup'">
  82. <div class="api-lookup-field">
  83. <input class="input" type="text"
  84. :name="`attribute_values[${attr.name}]`"
  85. x-model="attributeValues[attr.name]"
  86. :placeholder="attr.type === 'customer_lookup' ? 'Type to search customers…' : 'Type to search…'"
  87. autocomplete="off"
  88. x-on:focus="openApiLookup(attr.name)"
  89. x-on:blur="closeApiLookup(attr.name)"
  90. x-on:keydown.escape.prevent="closeApiLookup(attr.name)">
  91. <div class="api-lookup-dropdown"
  92. x-show="apiLookupOpen[attr.name]"
  93. x-on:mousedown.prevent>
  94. <p class="api-lookup-loading" x-show="apiLookupState[attr.name] === 'loading'">Loading…</p>
  95. <div class="api-lookup-table" x-show="apiLookupState[attr.name] !== 'loading' && apiLookupState[attr.name] !== 'error'">
  96. <div class="api-lookup-thead"
  97. :style="`grid-template-columns: repeat(${getApiOptions(attr.name).fields.length || 1}, 1fr)`">
  98. <template x-for="f in getApiOptions(attr.name).fields" :key="f">
  99. <span x-text="f"></span>
  100. </template>
  101. </div>
  102. <div class="api-lookup-tbody">
  103. <template x-for="rec in getFilteredRecords(attr.name, attributeValues[attr.name])" :key="rec._primary">
  104. <div class="api-lookup-tr"
  105. :class="{ 'is-selected': attributeValues[attr.name] === rec._primary }"
  106. :style="`grid-template-columns: repeat(${getApiOptions(attr.name).fields.length || 1}, 1fr)`"
  107. x-on:click="selectApiOption(attr, rec)">
  108. <template x-for="(v, i) in rec._display" :key="i">
  109. <span x-text="v"></span>
  110. </template>
  111. </div>
  112. </template>
  113. <div class="api-lookup-empty" x-show="!getFilteredRecords(attr.name, attributeValues[attr.name]).length">No results.</div>
  114. </div>
  115. </div>
  116. <small class="field-error" x-show="apiLookupState[attr.name] === 'error'" x-text="apiLookupError[attr.name] || 'Fetch failed.'"></small>
  117. </div>
  118. </div>
  119. </template>
  120. <template x-if="attr.type !== 'boolean' && attr.type !== 'api_lookup' && attr.type !== 'customer_lookup'">
  121. <input class="input" :type="inputType(attr.type)"
  122. :name="`attribute_values[${attr.name}]`"
  123. :value="attributeValues[attr.name] ?? ''"
  124. x-on:input="attributeValues[attr.name] = $event.target.value">
  125. </template>
  126. </label>
  127. </template>
  128. </div>
  129. </div>
  130. <p class="attributes-hint" x-show="selectedTypeId && currentAttributes.length === 0">
  131. This job type has no attributes defined.
  132. </p>
  133. <div class="form-actions">
  134. <button class="button button-primary" type="submit">Save Job</button>
  135. <a class="button button-secondary" href="/jobs">Cancel</a>
  136. </div>
  137. </form>
  138. </section>
  139. <?php endif; ?>
  140. </section>

Powered by TurnKey Linux.