Skip to content

Instantly share code, notes, and snippets.

@Lepozepo
Created January 7, 2021 19:18
Show Gist options
  • Save Lepozepo/7d0fb2372fd2d3e324bc2a9636831a26 to your computer and use it in GitHub Desktop.
Save Lepozepo/7d0fb2372fd2d3e324bc2a9636831a26 to your computer and use it in GitHub Desktop.
import Fields from 'graphql-fields';
import isEmpty from 'lodash/isEmpty';
import q from '~/config/q';
import dataPage from '~/utils/dataPage';
import geocode from '~/utils/geocode';
export default async function devices(root, props, context, info) {
const {
db,
ownerId,
connector,
isSysAdmin,
} = context;
const {
filter,
sort,
limit = 64,
cursor,
} = props?.list || {};
const fields = Fields(info, {}, { excludedFields: ['__typename'], processArguments: true });
let locationCoords;
if (filter?.location) {
const geolocation = await geocode({
address: filter.location.address,
}).catch(() => null);
locationCoords = geolocation?.geometry?.location;
}
const sorter = q.Index(`devices_${(sort?.by || 'createdAt').replace('.', '_')}_${sort?.direction || 'desc'}`);
const base = q.Index('devices_natural_asc');
return db.query(
dataPage({
set: q.Join(
q.Intersection.apply(this, [
...(filter?.organizationId === 'all' && isSysAdmin ? [
q.Join(
q.Documents(q.Collection('devices')),
base,
),
] : [
q.Join(
q.Match(q.Index('ownersNodes_node_by_ownerId'), (!isEmpty(filter?.organizationId) && isSysAdmin) ? q.Ref(q.Collection('organizations'), filter?.organizationId) : ownerId),
base,
),
]),
// model filter
...(!isEmpty(filter?.model) ? [q.Join(
q.Match(q.Index('devices_by_model'), filter.model),
base,
)] : []),
// status filter
...(!isEmpty(filter?.status) ? [q.Join(
q.Match(q.Index('devices_by_status'), filter.status),
base,
)] : []),
// firmware version filter
...(filter?.versions?.length > 0 ? [q.Join(
q.Union.apply(this, filter.versions.map((version) => (
q.Match(q.Index('devices_by_firmware_version'), version)
))),
base,
)] : []),
// tag filter
...(filter?.tagIds?.length > 0 ? [q.Join(
q.Intersection.apply(this, filter.tagIds.map((tagId) => (
q.Match(
q.Index('devicesTags_device_by_tagId'),
q.Ref(q.Collection('tags'), tagId),
)
))),
base,
)] : []),
// workflows filter
...(filter?.workflowIds?.length > 0 ? [q.Join(
q.Union.apply(this, filter.workflowIds.map((workflowId) => (
q.Match(
q.Index('workflowsDevices_device_by_workflowId'),
q.Ref(q.Collection('workflows'), workflowId),
)
))),
base,
)] : []),
// skills filter
...(filter?.skillIds?.length > 0 ? [q.Join(
q.Union.apply(this, filter.skillIds.map((skillId) => (
q.Join(
q.Join(
q.Match(q.Index('skillVersions_by_skillId'), q.Ref(q.Collection('skills'), skillId)),
q.Index('workflowsSkills_workflow_by_skillVersionId'),
),
q.Index('workflowsDevices_device_by_workflowId'),
)
))),
base,
)] : []),
// groups filter
...(filter?.groupIds?.length > 0 ? [q.Join(
q.Union.apply(this, filter.groupIds.map((groupId) => (
q.Join(
q.Match(
q.Index('workflowDeviceGroupsMembers_workflowDevice_by_groupId'),
q.Ref(q.Collection('workflowsDeviceGroups'), groupId),
),
q.Index('workflowsDevices_device_by_ref'),
)
))),
base,
)] : []),
// downtime filter
...(!isEmpty(filter?.downtime?.downAt) ? [q.Join(
q.Filter(
q.Match(q.Index('devices_by_downtime_down_with_downAt'), true),
q.Lambda((idx) => (
q.And.apply(this, Object.entries(filter.downtime.downAt).map(([k, v]) => (
q[k](q.Select(1, idx), q.ToTime(v))
)))
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
)] : []),
// cpu filter
...(!isEmpty(filter?.cpu?.avgLoadPercent15Min) ? [q.Join(
q.Filter(
q.Match(q.Index('devices_with_avgLoadPercent15Min')),
q.Lambda((idx) => (
q.And.apply(this, Object.entries(filter.cpu.avgLoadPercent15Min).map(([k, v]) => (
q[k](q.Select(1, idx), v)
)))
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
)] : []),
// ram filter
...(!isEmpty(filter?.ram?.availablePercent) ? [q.Join(
q.Filter(
q.Match(q.Index('devices_with_ram_availablePercent')),
q.Lambda((idx) => (
q.And.apply(this, Object.entries(filter.ram.availablePercent).map(([k, v]) => (
q[k](q.Select(1, idx), v)
)))
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
)] : []),
// disk filter
...(!isEmpty(filter?.disk?.availablePercent) ? [q.Join(
q.Filter(
q.Match(q.Index('devices_with_disk_availablePercent')),
q.Lambda((idx) => (
q.And.apply(this, Object.entries(filter.disk.availablePercent).map(([k, v]) => (
q[k](q.Select(1, idx), v)
)))
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
)] : []),
// location filter
...(!isEmpty(locationCoords) ? [q.Join(
q.Filter(
q.Match(q.Index('devices_with_location')),
q.Lambda((idx) => (
q.Let(
{
latUpperLimit: locationCoords.lat + (parseFloat(filter.location.radius) / 69),
latLowerLimit: locationCoords.lat - (parseFloat(filter.location.radius) / 69),
lngUpperLimit: locationCoords.lng + (parseFloat(filter.location.radius) / 54.6),
lngLowerLimit: locationCoords.lng - (parseFloat(filter.location.radius) / 54.6),
lat: q.Select(1, idx),
lng: q.Select(2, idx),
},
q.All([
q.GTE(q.Var('lat'), q.Var('latLowerLimit')),
q.LTE(q.Var('lat'), q.Var('latUpperLimit')),
q.GTE(q.Var('lng'), q.Var('lngLowerLimit')),
q.LTE(q.Var('lng'), q.Var('lngUpperLimit')),
]),
)
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
)] : []),
// search filter
...(!isEmpty(filter?.$search) ? [
q.Union(
// search by MAC address
q.Join(
q.Match(q.Index('devices_by_mac'), filter.$search),
base,
),
// search by IP
q.Join(
q.Match(q.Index('devices_by_ip'), filter.$search),
base,
),
// q.Join(
// q.Filter(
// q.Match(q.Index('devices_with_ip')),
// q.Lambda((idx) => (
// q.ContainsStr(
// q.If(
// q.IsNull(q.Select(1, idx, '')),
// '',
// q.Select(1, idx, ''),
// ),
// filter.$search,
// )
// )),
// ),
// q.Lambda((idx) => (
// q.Match(base, q.Select(0, idx))
// )),
// ),
// search device barcode filter
q.Join(
q.Match(q.Index('devices_by_serialNumber'), filter.$search),
base,
),
// search device name filter
q.Join(
q.Filter(
q.Match(q.Index('devices_with_name')),
q.Lambda((idx) => (
q.ContainsStr(
q.LowerCase(q.Select(1, idx, '')),
q.LowerCase(filter.$search),
)
)),
),
q.Lambda((idx) => (
q.Match(base, q.Select(0, idx))
)),
),
// search tag name filter
q.Join(
q.Join(
q.Filter(
q.Match(q.Index('tags_with_name')),
q.Lambda((idx) => (
q.ContainsStr(
q.LowerCase(q.Select(1, idx, '')),
q.LowerCase(filter.$search),
)
)),
),
q.Lambda((idx) => (
q.Match(q.Index('devicesTags_device_by_tagId'), q.Select(0, idx))
)),
),
base,
),
),
] : []),
]),
sorter,
),
pagination: {
...cursor,
size: limit,
},
fields,
lambda: (doc) => (
connector({
doc,
type: 'Device',
fields: fields.data,
context,
})
),
}),
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment