選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

158 行
7.3KB

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

Powered by TurnKey Linux.