Repo for the search and displace core module including the interface to select files and search and displace operations to run on them. https://searchanddisplace.com
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.

188 lines
5.5 KiB

  1. <template>
  2. <div id="searchers-create">
  3. <div>
  4. <h1> {{ searcher.id ? 'Edit' : 'New' }} searcher </h1>
  5. <InputText v-model="name"
  6. type="text"
  7. placeholder="Enter searcher name"
  8. class="input">
  9. </InputText>
  10. <Button @click="onSave" :disabled=" ! name || rows.length === 0">
  11. Save
  12. </Button>
  13. </div>
  14. <div v-if="standalone">
  15. <p>
  16. A searcher may contain multiple compounded searchers on multiple rows and columns.
  17. </p>
  18. <p>
  19. Each searcher in a row is extending the searching criteria on the content resulted from the
  20. previous row searchers.
  21. </p>
  22. </div>
  23. <div v-for="(row, rowIndex) in rows"
  24. :key="`row-${rowIndex}`"
  25. class="searchers-row flex-row">
  26. <div v-for="(searcher, columnIndex) in row"
  27. :key="`column-${columnIndex}`"
  28. class="searcher box">
  29. <searcher-show :searcher="searcher"
  30. :editable="true"
  31. :standalone="false"
  32. @deleted="onRemoveItem(rowIndex, columnIndex)">
  33. </searcher-show>
  34. </div>
  35. <add-box :ignore-searcher-ids="searcher.id ? [searcher.id] : []"
  36. @added="(searcher) => { onSearcherAdded(searcher, rowIndex); }">
  37. </add-box>
  38. </div>
  39. <div class="searchers-row flex-row">
  40. <add-box @added="onNewRowSearcherAdded">
  41. </add-box>
  42. </div>
  43. </div>
  44. </template>
  45. <script lang="ts">
  46. import { eventBus } from "@/app";
  47. import {Component, Prop, Vue} from "vue-property-decorator";
  48. import AddBox from './AddBox.vue';
  49. import SearcherShow from './Show.vue';
  50. @Component({
  51. name: 'SearcherCreate',
  52. components: {
  53. AddBox,
  54. SearcherShow,
  55. },
  56. })
  57. export default class Create extends Vue {
  58. private id: String = '';
  59. private name: String = '';
  60. private rows: Array<Array<any>> = [];
  61. @Prop({
  62. default: () => {
  63. return {
  64. id: '',
  65. name: '',
  66. rows: [],
  67. };
  68. }
  69. })
  70. public readonly searcher!: any;
  71. @Prop({default: true})
  72. public readonly standalone!: boolean;
  73. onNewRowSearcherAdded(searcher: Object) {
  74. const length = this.rows.push([]);
  75. this.onSearcherAdded(searcher, length - 1);
  76. }
  77. async onSearcherAdded(searcher: any, rowIndex: number) {
  78. try {
  79. const { data } = await (window as any).axios.get(`/searchers/${searcher.id}`);
  80. this.rows[rowIndex].push(data.searcher);
  81. } catch (e) {
  82. }
  83. }
  84. onSave() {
  85. if (this.standalone) {
  86. this.save();
  87. return;
  88. }
  89. const updatedSearcher = Object.assign(this.searcher, {
  90. name: this.name,
  91. rows: this.rows,
  92. });
  93. this.$emit('updated', updatedSearcher);
  94. }
  95. async save() {
  96. try {
  97. const searcher = this.id ? await this.update() : await this.create();
  98. window.location.href = `/searchers/${searcher.id}`;
  99. } catch (e) {
  100. console.log(e);
  101. console.log('Something went wrong.');
  102. }
  103. }
  104. async update() {
  105. const { data } = await (window as any).axios.put(`/searchers/${this.id}`, {
  106. name: this.name,
  107. rows: this.rows,
  108. });
  109. return data.searcher;
  110. }
  111. async create() {
  112. const { data } = await (window as any).axios.post('/searchers', {
  113. name: this.name,
  114. rows: this.rows,
  115. });
  116. return data.searcher;
  117. }
  118. onRemoveItem(rowIndex: number, columnIndex: number) {
  119. if (
  120. this.rows[rowIndex][columnIndex].hasOwnProperty('rows') &&
  121. this.rows[rowIndex][columnIndex].rows.length === 0
  122. ) {
  123. this.$toast.add({
  124. severity: 'info',
  125. summary: `${this.searcher.name} searcher deleted`,
  126. detail: 'The searcher has been deleted as well because it does not have any searching data..',
  127. life: 4000,
  128. });
  129. }
  130. this.rows[rowIndex].splice(columnIndex, 1);
  131. if (this.rows[rowIndex].length === 0) {
  132. this.rows.splice(rowIndex, 1);
  133. }
  134. }
  135. public async changeRoute(url: string) {
  136. if (this.rows.length > 0) {
  137. if (this.name === '' || this.name === undefined) {
  138. this.name = 'Unnamed searcher - ' + Date.now();
  139. }
  140. const searcher = this.id ? await this.update() : await this.create();
  141. }
  142. window.location.href = url;
  143. }
  144. created() {
  145. // Editing.
  146. if (this.searcher.id) {
  147. this.id = this.searcher.id;
  148. this.rows = this.searcher.rows;
  149. this.name = this.searcher.name;
  150. }
  151. eventBus.$on('changeRoute', this.changeRoute);
  152. }
  153. };
  154. </script>