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.

153 lines
6.9KB

  1. <?php
  2. $campaignId = (int) ($campaign['id'] ?? 0);
  3. $campaignTypeName = (string) ($campaign['campaign_type_name'] ?? '');
  4. ?>
  5. <script>
  6. window.__campaignJobTypes = <?= json_encode($jobTypes ?? [], JSON_HEX_TAG | JSON_THROW_ON_ERROR) ?>;
  7. </script>
  8. <section class="content-stack" x-data="campaignJobsPageTable(<?= $campaignId ?>, window.__campaignJobTypes)">
  9. <div class="page-toolbar">
  10. <div class="section-heading">
  11. <h1>Campaign Jobs</h1>
  12. <p><?= e($campaignTypeName) ?> #<?= e((string) $campaignId) ?></p>
  13. </div>
  14. <div class="panel-actions">
  15. <a class="button button-secondary" href="/campaigns">&larr; Back to campaigns</a>
  16. <a class="button button-primary" href="/jobs/create">+ New Job</a>
  17. </div>
  18. </div>
  19. <section class="section-panel">
  20. <div class="panel-header">
  21. <h2>Import Jobs</h2>
  22. </div>
  23. <!-- Source tabs -->
  24. <div class="import-tabs">
  25. <button type="button"
  26. class="import-tab"
  27. :class="importSource === 'sheets' ? 'is-active' : ''"
  28. x-on:click="importSource = 'sheets'">Google Sheets</button>
  29. <button type="button"
  30. class="import-tab"
  31. :class="importSource === 'file' ? 'is-active' : ''"
  32. x-on:click="importSource = 'file'">CSV / Excel</button>
  33. </div>
  34. <!-- Google Sheets panel -->
  35. <div x-show="importSource === 'sheets'">
  36. <p class="attributes-hint" style="margin-bottom:1rem">
  37. The spreadsheet must be shared as <strong>Anyone with the link can view</strong>.
  38. </p>
  39. <div class="import-grid">
  40. <label class="field">
  41. <span>Google Sheets URL</span>
  42. <input class="input" type="url" x-model="importSheetUrl"
  43. placeholder="https://docs.google.com/spreadsheets/d/...">
  44. </label>
  45. <label class="field">
  46. <span>Sheet</span>
  47. <select class="input" x-model="selectedSheetGid" :disabled="sheets.length === 0">
  48. <option value="">Select a sheet</option>
  49. <template x-for="sheet in sheets" :key="sheet.gid">
  50. <option :value="sheet.gid" x-text="sheet.title"></option>
  51. </template>
  52. </select>
  53. </label>
  54. <label class="field">
  55. <span>Job type</span>
  56. <select class="input" x-model="selectedImportJobTypeId">
  57. <option value="0">Select a job type</option>
  58. <template x-for="jt in jobTypes" :key="jt.id">
  59. <option :value="jt.id" x-text="jt.name"></option>
  60. </template>
  61. </select>
  62. </label>
  63. </div>
  64. <div class="form-actions import-actions">
  65. <button class="button button-secondary" type="button"
  66. x-on:click="connectGoogleSheet()" :disabled="isConnecting">Connect</button>
  67. <button class="button button-primary" type="button"
  68. x-on:click="importGoogleSheet()"
  69. :disabled="isImporting || !selectedSheetGid || Number(selectedImportJobTypeId) === 0">
  70. Import
  71. </button>
  72. <span class="inline-indicator" x-show="isConnecting">Connecting...</span>
  73. <span class="inline-indicator" x-show="isImporting">Importing...</span>
  74. </div>
  75. </div>
  76. <!-- File upload panel -->
  77. <div x-show="importSource === 'file'">
  78. <p class="attributes-hint" style="margin-bottom:1rem">
  79. Export your sheet as <strong>CSV</strong> or <strong>Excel (.xlsx)</strong> from Google Sheets, then upload it here.
  80. </p>
  81. <div class="import-grid">
  82. <label class="field">
  83. <span>CSV or Excel file (.csv, .xlsx)</span>
  84. <input class="input" type="file" accept=".csv,.xlsx"
  85. x-ref="fileInput" x-on:change="onFileSelect($event)">
  86. </label>
  87. <label class="field">
  88. <span>Sheet</span>
  89. <select class="input" x-model="selectedFileSheetGid" :disabled="fileSheets.length === 0">
  90. <option value="">Select a sheet</option>
  91. <template x-for="sheet in fileSheets" :key="sheet.gid">
  92. <option :value="sheet.gid" x-text="sheet.title"></option>
  93. </template>
  94. </select>
  95. </label>
  96. <label class="field">
  97. <span>Job type</span>
  98. <select class="input" x-model="selectedFileJobTypeId">
  99. <option value="0">Select a job type</option>
  100. <template x-for="jt in jobTypes" :key="jt.id">
  101. <option :value="jt.id" x-text="jt.name"></option>
  102. </template>
  103. </select>
  104. </label>
  105. </div>
  106. <div class="form-actions import-actions">
  107. <button class="button button-secondary" type="button"
  108. x-on:click="loadFileSheets()" :disabled="isLoadingFile || !fileSelected">
  109. Load Sheets
  110. </button>
  111. <button class="button button-primary" type="button"
  112. x-on:click="importFile()"
  113. :disabled="isImportingFile || !fileTempName || !selectedFileSheetGid || Number(selectedFileJobTypeId) === 0">
  114. Import
  115. </button>
  116. <span class="inline-indicator" x-show="isLoadingFile">Reading file...</span>
  117. <span class="inline-indicator" x-show="isImportingFile">Importing...</span>
  118. </div>
  119. </div>
  120. <!-- Shared result messages -->
  121. <div class="alert alert-success" x-cloak x-show="importMessage" x-text="importMessage"></div>
  122. <div class="alert alert-error" x-cloak x-show="importErrorMessage" x-text="importErrorMessage"></div>
  123. </section>
  124. <section class="section-panel">
  125. <div class="panel-header">
  126. <div>
  127. <h2>Job Directory</h2>
  128. <p>All jobs in this campaign with job fields and attribute fields.</p>
  129. </div>
  130. <button class="button button-secondary" type="button" x-on:click="reloadTable()">Refresh</button>
  131. </div>
  132. <div class="inline-indicator" x-cloak x-show="isLoading">Loading jobs...</div>
  133. <div class="alert alert-error" x-cloak x-show="errorMessage" x-text="errorMessage"></div>
  134. <div id="campaign-jobs-page-table" class="tabulator-host"></div>
  135. </section>
  136. </section>

Powered by TurnKey Linux.